mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
Merge pull request #18427 from ChayimFriedman2/cleanup-ty
Cleanup TypeRef lowering
This commit is contained in:
commit
3fd6a72556
12 changed files with 151 additions and 170 deletions
|
@ -407,7 +407,7 @@ impl ExprCollector<'_> {
|
||||||
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
|
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
|
||||||
let generic_args = e
|
let generic_args = e
|
||||||
.generic_arg_list()
|
.generic_arg_list()
|
||||||
.and_then(|it| GenericArgs::from_ast(&self.ctx(), it))
|
.and_then(|it| GenericArgs::from_ast(&mut self.ctx(), it))
|
||||||
.map(Box::new);
|
.map(Box::new);
|
||||||
self.alloc_expr(
|
self.alloc_expr(
|
||||||
Expr::MethodCall { receiver, method_name, args, generic_args },
|
Expr::MethodCall { receiver, method_name, args, generic_args },
|
||||||
|
@ -533,7 +533,7 @@ impl ExprCollector<'_> {
|
||||||
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
|
ast::Expr::TryExpr(e) => self.collect_try_operator(syntax_ptr, e),
|
||||||
ast::Expr::CastExpr(e) => {
|
ast::Expr::CastExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
|
let type_ref = TypeRef::from_ast_opt(&mut self.ctx(), e.ty());
|
||||||
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::RefExpr(e) => {
|
ast::Expr::RefExpr(e) => {
|
||||||
|
@ -572,13 +572,15 @@ impl ExprCollector<'_> {
|
||||||
arg_types.reserve_exact(num_params);
|
arg_types.reserve_exact(num_params);
|
||||||
for param in pl.params() {
|
for param in pl.params() {
|
||||||
let pat = this.collect_pat_top(param.pat());
|
let pat = this.collect_pat_top(param.pat());
|
||||||
let type_ref = param.ty().map(|it| TypeRef::from_ast(&this.ctx(), it));
|
let type_ref = param.ty().map(|it| TypeRef::from_ast(&mut this.ctx(), it));
|
||||||
args.push(pat);
|
args.push(pat);
|
||||||
arg_types.push(type_ref);
|
arg_types.push(type_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ret_type =
|
let ret_type = e
|
||||||
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&this.ctx(), it));
|
.ret_type()
|
||||||
|
.and_then(|r| r.ty())
|
||||||
|
.map(|it| TypeRef::from_ast(&mut this.ctx(), it));
|
||||||
|
|
||||||
let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
|
let prev_is_lowering_coroutine = mem::take(&mut this.is_lowering_coroutine);
|
||||||
let prev_try_block_label = this.current_try_block_label.take();
|
let prev_try_block_label = this.current_try_block_label.take();
|
||||||
|
@ -705,7 +707,7 @@ impl ExprCollector<'_> {
|
||||||
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
|
ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
|
||||||
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
|
ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
|
||||||
ast::Expr::OffsetOfExpr(e) => {
|
ast::Expr::OffsetOfExpr(e) => {
|
||||||
let container = TypeRef::from_ast_opt(&self.ctx(), e.ty());
|
let container = TypeRef::from_ast_opt(&mut self.ctx(), e.ty());
|
||||||
let fields = e.fields().map(|it| it.as_name()).collect();
|
let fields = e.fields().map(|it| it.as_name()).collect();
|
||||||
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
|
self.alloc_expr(Expr::OffsetOf(OffsetOf { container, fields }), syntax_ptr)
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1319,7 @@ impl ExprCollector<'_> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let pat = self.collect_pat_top(stmt.pat());
|
let pat = self.collect_pat_top(stmt.pat());
|
||||||
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it));
|
let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&mut self.ctx(), it));
|
||||||
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
|
let initializer = stmt.initializer().map(|e| self.collect_expr(e));
|
||||||
let else_branch = stmt
|
let else_branch = stmt
|
||||||
.let_else()
|
.let_else()
|
||||||
|
|
|
@ -161,14 +161,14 @@ impl Expander {
|
||||||
types_map: &mut TypesMap,
|
types_map: &mut TypesMap,
|
||||||
types_source_map: &mut TypesSourceMap,
|
types_source_map: &mut TypesSourceMap,
|
||||||
) -> Option<Path> {
|
) -> Option<Path> {
|
||||||
let ctx = LowerCtx::with_span_map_cell(
|
let mut ctx = LowerCtx::with_span_map_cell(
|
||||||
db,
|
db,
|
||||||
self.current_file_id,
|
self.current_file_id,
|
||||||
self.span_map.clone(),
|
self.span_map.clone(),
|
||||||
types_map,
|
types_map,
|
||||||
types_source_map,
|
types_source_map,
|
||||||
);
|
);
|
||||||
Path::from_src(&ctx, path)
|
Path::from_src(&mut ctx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn within_limit<F, T: ast::AstNode>(
|
fn within_limit<F, T: ast::AstNode>(
|
||||||
|
|
|
@ -451,7 +451,7 @@ pub(crate) struct GenericParamsCollector {
|
||||||
impl GenericParamsCollector {
|
impl GenericParamsCollector {
|
||||||
pub(crate) fn fill(
|
pub(crate) fn fill(
|
||||||
&mut self,
|
&mut self,
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
node: &dyn HasGenericParams,
|
node: &dyn HasGenericParams,
|
||||||
add_param_attrs: impl FnMut(
|
add_param_attrs: impl FnMut(
|
||||||
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
||||||
|
@ -468,7 +468,7 @@ impl GenericParamsCollector {
|
||||||
|
|
||||||
pub(crate) fn fill_bounds(
|
pub(crate) fn fill_bounds(
|
||||||
&mut self,
|
&mut self,
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
type_bounds: Option<ast::TypeBoundList>,
|
type_bounds: Option<ast::TypeBoundList>,
|
||||||
target: Either<TypeRefId, LifetimeRef>,
|
target: Either<TypeRefId, LifetimeRef>,
|
||||||
) {
|
) {
|
||||||
|
@ -479,7 +479,7 @@ impl GenericParamsCollector {
|
||||||
|
|
||||||
fn fill_params(
|
fn fill_params(
|
||||||
&mut self,
|
&mut self,
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
params: ast::GenericParamList,
|
params: ast::GenericParamList,
|
||||||
mut add_param_attrs: impl FnMut(
|
mut add_param_attrs: impl FnMut(
|
||||||
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
||||||
|
@ -535,7 +535,11 @@ impl GenericParamsCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx<'_>, where_clause: ast::WhereClause) {
|
fn fill_where_predicates(
|
||||||
|
&mut self,
|
||||||
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
|
where_clause: ast::WhereClause,
|
||||||
|
) {
|
||||||
for pred in where_clause.predicates() {
|
for pred in where_clause.predicates() {
|
||||||
let target = if let Some(type_ref) = pred.ty() {
|
let target = if let Some(type_ref) = pred.ty() {
|
||||||
Either::Left(TypeRef::from_ast(lower_ctx, type_ref))
|
Either::Left(TypeRef::from_ast(lower_ctx, type_ref))
|
||||||
|
@ -569,7 +573,7 @@ impl GenericParamsCollector {
|
||||||
|
|
||||||
fn add_where_predicate_from_bound(
|
fn add_where_predicate_from_bound(
|
||||||
&mut self,
|
&mut self,
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
bound: ast::TypeBound,
|
bound: ast::TypeBound,
|
||||||
hrtb_lifetimes: Option<&[Name]>,
|
hrtb_lifetimes: Option<&[Name]>,
|
||||||
target: Either<TypeRefId, LifetimeRef>,
|
target: Either<TypeRefId, LifetimeRef>,
|
||||||
|
@ -670,8 +674,9 @@ impl GenericParamsCollector {
|
||||||
{
|
{
|
||||||
let (mut macro_types_map, mut macro_types_source_map) =
|
let (mut macro_types_map, mut macro_types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx = expander.ctx(db, &mut macro_types_map, &mut macro_types_source_map);
|
let mut ctx =
|
||||||
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
|
expander.ctx(db, &mut macro_types_map, &mut macro_types_source_map);
|
||||||
|
let type_ref = TypeRef::from_ast(&mut ctx, expanded.tree());
|
||||||
self.fill_implicit_impl_trait_args(
|
self.fill_implicit_impl_trait_args(
|
||||||
db,
|
db,
|
||||||
generics_types_map,
|
generics_types_map,
|
||||||
|
|
|
@ -98,7 +98,7 @@ pub struct TraitRef {
|
||||||
|
|
||||||
impl TraitRef {
|
impl TraitRef {
|
||||||
/// Converts an `ast::PathType` to a `hir::TraitRef`.
|
/// Converts an `ast::PathType` to a `hir::TraitRef`.
|
||||||
pub(crate) fn from_ast(ctx: &LowerCtx<'_>, node: ast::Type) -> Option<Self> {
|
pub(crate) fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::Type) -> Option<Self> {
|
||||||
// FIXME: Use `Path::from_src`
|
// FIXME: Use `Path::from_src`
|
||||||
match node {
|
match node {
|
||||||
ast::Type::PathType(path) => {
|
ast::Type::PathType(path) => {
|
||||||
|
@ -240,7 +240,7 @@ pub enum TraitBoundModifier {
|
||||||
|
|
||||||
impl TypeRef {
|
impl TypeRef {
|
||||||
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
||||||
pub fn from_ast(ctx: &LowerCtx<'_>, node: ast::Type) -> TypeRefId {
|
pub fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::Type) -> TypeRefId {
|
||||||
let ty = match &node {
|
let ty = match &node {
|
||||||
ast::Type::ParenType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
|
ast::Type::ParenType(inner) => return TypeRef::from_ast_opt(ctx, inner.ty()),
|
||||||
ast::Type::TupleType(inner) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
|
ast::Type::TupleType(inner) => TypeRef::Tuple(EmptyOptimizedThinVec::from_iter(
|
||||||
|
@ -321,8 +321,9 @@ impl TypeRef {
|
||||||
// Disallow nested impl traits
|
// Disallow nested impl traits
|
||||||
TypeRef::Error
|
TypeRef::Error
|
||||||
} else {
|
} else {
|
||||||
let _guard = ctx.outer_impl_trait_scope(true);
|
ctx.with_outer_impl_trait_scope(true, |ctx| {
|
||||||
TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
|
TypeRef::ImplTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Type::DynTraitType(inner) => {
|
ast::Type::DynTraitType(inner) => {
|
||||||
|
@ -336,7 +337,7 @@ impl TypeRef {
|
||||||
ctx.alloc_type_ref(ty, AstPtr::new(&node))
|
ctx.alloc_type_ref(ty, AstPtr::new(&node))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_ast_opt(ctx: &LowerCtx<'_>, node: Option<ast::Type>) -> TypeRefId {
|
pub(crate) fn from_ast_opt(ctx: &mut LowerCtx<'_>, node: Option<ast::Type>) -> TypeRefId {
|
||||||
match node {
|
match node {
|
||||||
Some(node) => TypeRef::from_ast(ctx, node),
|
Some(node) => TypeRef::from_ast(ctx, node),
|
||||||
None => ctx.alloc_error_type(),
|
None => ctx.alloc_error_type(),
|
||||||
|
@ -410,7 +411,7 @@ impl TypeRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn type_bounds_from_ast(
|
pub(crate) fn type_bounds_from_ast(
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
type_bounds_opt: Option<ast::TypeBoundList>,
|
type_bounds_opt: Option<ast::TypeBoundList>,
|
||||||
) -> ThinVec<TypeBound> {
|
) -> ThinVec<TypeBound> {
|
||||||
if let Some(type_bounds) = type_bounds_opt {
|
if let Some(type_bounds) = type_bounds_opt {
|
||||||
|
@ -423,8 +424,8 @@ pub(crate) fn type_bounds_from_ast(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeBound {
|
impl TypeBound {
|
||||||
pub(crate) fn from_ast(ctx: &LowerCtx<'_>, node: ast::TypeBound) -> Self {
|
pub(crate) fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::TypeBound) -> Self {
|
||||||
let lower_path_type = |path_type: ast::PathType| ctx.lower_path(path_type.path()?);
|
let mut lower_path_type = |path_type: ast::PathType| ctx.lower_path(path_type.path()?);
|
||||||
|
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
ast::TypeBoundKind::PathType(path_type) => {
|
ast::TypeBoundKind::PathType(path_type) => {
|
||||||
|
|
|
@ -234,11 +234,11 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
|
fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let visibility = self.lower_visibility(strukt);
|
let visibility = self.lower_visibility(strukt);
|
||||||
let name = strukt.name()?.as_name();
|
let name = strukt.name()?.as_name();
|
||||||
let ast_id = self.source_ast_id_map.ast_id(strukt);
|
let ast_id = self.source_ast_id_map.ast_id(strukt);
|
||||||
let (fields, kind, attrs) = self.lower_fields(&strukt.kind(), &body_ctx);
|
let (fields, kind, attrs) = self.lower_fields(&strukt.kind(), &mut body_ctx);
|
||||||
let (generic_params, generics_source_map) =
|
let (generic_params, generics_source_map) =
|
||||||
self.lower_generic_params(HasImplicitSelf::No, strukt);
|
self.lower_generic_params(HasImplicitSelf::No, strukt);
|
||||||
types_map.shrink_to_fit();
|
types_map.shrink_to_fit();
|
||||||
|
@ -273,7 +273,7 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_fields(
|
fn lower_fields(
|
||||||
&mut self,
|
&mut self,
|
||||||
strukt_kind: &ast::StructKind,
|
strukt_kind: &ast::StructKind,
|
||||||
body_ctx: &LowerCtx<'_>,
|
body_ctx: &mut LowerCtx<'_>,
|
||||||
) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
|
) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) {
|
||||||
match strukt_kind {
|
match strukt_kind {
|
||||||
ast::StructKind::Record(it) => {
|
ast::StructKind::Record(it) => {
|
||||||
|
@ -308,7 +308,11 @@ impl<'a> Ctx<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_record_field(&mut self, field: &ast::RecordField, body_ctx: &LowerCtx<'_>) -> Field {
|
fn lower_record_field(
|
||||||
|
&mut self,
|
||||||
|
field: &ast::RecordField,
|
||||||
|
body_ctx: &mut LowerCtx<'_>,
|
||||||
|
) -> Field {
|
||||||
let name = match field.name() {
|
let name = match field.name() {
|
||||||
Some(name) => name.as_name(),
|
Some(name) => name.as_name(),
|
||||||
None => Name::missing(),
|
None => Name::missing(),
|
||||||
|
@ -323,7 +327,7 @@ impl<'a> Ctx<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
field: &ast::TupleField,
|
field: &ast::TupleField,
|
||||||
body_ctx: &LowerCtx<'_>,
|
body_ctx: &mut LowerCtx<'_>,
|
||||||
) -> Field {
|
) -> Field {
|
||||||
let name = Name::new_tuple_field(idx);
|
let name = Name::new_tuple_field(idx);
|
||||||
let visibility = self.lower_visibility(field);
|
let visibility = self.lower_visibility(field);
|
||||||
|
@ -334,13 +338,13 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
|
fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let visibility = self.lower_visibility(union);
|
let visibility = self.lower_visibility(union);
|
||||||
let name = union.name()?.as_name();
|
let name = union.name()?.as_name();
|
||||||
let ast_id = self.source_ast_id_map.ast_id(union);
|
let ast_id = self.source_ast_id_map.ast_id(union);
|
||||||
let (fields, _, attrs) = match union.record_field_list() {
|
let (fields, _, attrs) = match union.record_field_list() {
|
||||||
Some(record_field_list) => {
|
Some(record_field_list) => {
|
||||||
self.lower_fields(&StructKind::Record(record_field_list), &body_ctx)
|
self.lower_fields(&StructKind::Record(record_field_list), &mut body_ctx)
|
||||||
}
|
}
|
||||||
None => (Box::default(), FieldsShape::Record, Vec::default()),
|
None => (Box::default(), FieldsShape::Record, Vec::default()),
|
||||||
};
|
};
|
||||||
|
@ -409,12 +413,12 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
|
fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let name = match variant.name() {
|
let name = match variant.name() {
|
||||||
Some(name) => name.as_name(),
|
Some(name) => name.as_name(),
|
||||||
None => Name::missing(),
|
None => Name::missing(),
|
||||||
};
|
};
|
||||||
let (fields, kind, attrs) = self.lower_fields(&variant.kind(), &body_ctx);
|
let (fields, kind, attrs) = self.lower_fields(&variant.kind(), &mut body_ctx);
|
||||||
let ast_id = self.source_ast_id_map.ast_id(variant);
|
let ast_id = self.source_ast_id_map.ast_id(variant);
|
||||||
types_map.shrink_to_fit();
|
types_map.shrink_to_fit();
|
||||||
types_source_map.shrink_to_fit();
|
types_source_map.shrink_to_fit();
|
||||||
|
@ -436,7 +440,7 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
|
fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
|
|
||||||
let visibility = self.lower_visibility(func);
|
let visibility = self.lower_visibility(func);
|
||||||
let name = func.name()?.as_name();
|
let name = func.name()?.as_name();
|
||||||
|
@ -457,7 +461,7 @@ impl<'a> Ctx<'a> {
|
||||||
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
|
RawAttrs::new(self.db.upcast(), &self_param, self.span_map()),
|
||||||
);
|
);
|
||||||
let self_type = match self_param.ty() {
|
let self_type = match self_param.ty() {
|
||||||
Some(type_ref) => TypeRef::from_ast(&body_ctx, type_ref),
|
Some(type_ref) => TypeRef::from_ast(&mut body_ctx, type_ref),
|
||||||
None => {
|
None => {
|
||||||
let self_type = body_ctx.alloc_type_ref_desugared(TypeRef::Path(
|
let self_type = body_ctx.alloc_type_ref_desugared(TypeRef::Path(
|
||||||
Name::new_symbol_root(sym::Self_.clone()).into(),
|
Name::new_symbol_root(sym::Self_.clone()).into(),
|
||||||
|
@ -492,7 +496,7 @@ impl<'a> Ctx<'a> {
|
||||||
Param { type_ref: None }
|
Param { type_ref: None }
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let type_ref = TypeRef::from_ast_opt(&body_ctx, param.ty());
|
let type_ref = TypeRef::from_ast_opt(&mut body_ctx, param.ty());
|
||||||
Param { type_ref: Some(type_ref) }
|
Param { type_ref: Some(type_ref) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -502,7 +506,7 @@ impl<'a> Ctx<'a> {
|
||||||
|
|
||||||
let ret_type = match func.ret_type() {
|
let ret_type = match func.ret_type() {
|
||||||
Some(rt) => match rt.ty() {
|
Some(rt) => match rt.ty() {
|
||||||
Some(type_ref) => TypeRef::from_ast(&body_ctx, type_ref),
|
Some(type_ref) => TypeRef::from_ast(&mut body_ctx, type_ref),
|
||||||
None if rt.thin_arrow_token().is_some() => body_ctx.alloc_error_type(),
|
None if rt.thin_arrow_token().is_some() => body_ctx.alloc_error_type(),
|
||||||
None => body_ctx.alloc_type_ref_desugared(TypeRef::unit()),
|
None => body_ctx.alloc_type_ref_desugared(TypeRef::unit()),
|
||||||
},
|
},
|
||||||
|
@ -581,11 +585,11 @@ impl<'a> Ctx<'a> {
|
||||||
) -> Option<FileItemTreeId<TypeAlias>> {
|
) -> Option<FileItemTreeId<TypeAlias>> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let name = type_alias.name()?.as_name();
|
let name = type_alias.name()?.as_name();
|
||||||
let type_ref = type_alias.ty().map(|it| TypeRef::from_ast(&body_ctx, it));
|
let type_ref = type_alias.ty().map(|it| TypeRef::from_ast(&mut body_ctx, it));
|
||||||
let visibility = self.lower_visibility(type_alias);
|
let visibility = self.lower_visibility(type_alias);
|
||||||
let bounds = self.lower_type_bounds(type_alias, &body_ctx);
|
let bounds = self.lower_type_bounds(type_alias, &mut body_ctx);
|
||||||
let ast_id = self.source_ast_id_map.ast_id(type_alias);
|
let ast_id = self.source_ast_id_map.ast_id(type_alias);
|
||||||
let (generic_params, generics_source_map) =
|
let (generic_params, generics_source_map) =
|
||||||
self.lower_generic_params(HasImplicitSelf::No, type_alias);
|
self.lower_generic_params(HasImplicitSelf::No, type_alias);
|
||||||
|
@ -612,9 +616,9 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Static>> {
|
fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Static>> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let name = static_.name()?.as_name();
|
let name = static_.name()?.as_name();
|
||||||
let type_ref = TypeRef::from_ast_opt(&body_ctx, static_.ty());
|
let type_ref = TypeRef::from_ast_opt(&mut body_ctx, static_.ty());
|
||||||
let visibility = self.lower_visibility(static_);
|
let visibility = self.lower_visibility(static_);
|
||||||
let mutable = static_.mut_token().is_some();
|
let mutable = static_.mut_token().is_some();
|
||||||
let has_safe_kw = static_.safe_token().is_some();
|
let has_safe_kw = static_.safe_token().is_some();
|
||||||
|
@ -639,9 +643,9 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId<Const> {
|
fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId<Const> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
let name = konst.name().map(|it| it.as_name());
|
let name = konst.name().map(|it| it.as_name());
|
||||||
let type_ref = TypeRef::from_ast_opt(&body_ctx, konst.ty());
|
let type_ref = TypeRef::from_ast_opt(&mut body_ctx, konst.ty());
|
||||||
let visibility = self.lower_visibility(konst);
|
let visibility = self.lower_visibility(konst);
|
||||||
let ast_id = self.source_ast_id_map.ast_id(konst);
|
let ast_id = self.source_ast_id_map.ast_id(konst);
|
||||||
types_map.shrink_to_fit();
|
types_map.shrink_to_fit();
|
||||||
|
@ -724,14 +728,14 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
|
fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
|
|
||||||
let ast_id = self.source_ast_id_map.ast_id(impl_def);
|
let ast_id = self.source_ast_id_map.ast_id(impl_def);
|
||||||
// FIXME: If trait lowering fails, due to a non PathType for example, we treat this impl
|
// FIXME: If trait lowering fails, due to a non PathType for example, we treat this impl
|
||||||
// as if it was an non-trait impl. Ideally we want to create a unique missing ref that only
|
// as if it was an non-trait impl. Ideally we want to create a unique missing ref that only
|
||||||
// equals itself.
|
// equals itself.
|
||||||
let self_ty = TypeRef::from_ast_opt(&body_ctx, impl_def.self_ty());
|
let self_ty = TypeRef::from_ast_opt(&mut body_ctx, impl_def.self_ty());
|
||||||
let target_trait = impl_def.trait_().and_then(|tr| TraitRef::from_ast(&body_ctx, tr));
|
let target_trait = impl_def.trait_().and_then(|tr| TraitRef::from_ast(&mut body_ctx, tr));
|
||||||
let is_negative = impl_def.excl_token().is_some();
|
let is_negative = impl_def.excl_token().is_some();
|
||||||
let is_unsafe = impl_def.unsafe_token().is_some();
|
let is_unsafe = impl_def.unsafe_token().is_some();
|
||||||
|
|
||||||
|
@ -870,13 +874,8 @@ impl<'a> Ctx<'a> {
|
||||||
) -> (Arc<GenericParams>, TypesSourceMap) {
|
) -> (Arc<GenericParams>, TypesSourceMap) {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map);
|
||||||
debug_assert!(self.generic_param_attr_buffer.is_empty(),);
|
debug_assert!(self.generic_param_attr_buffer.is_empty(),);
|
||||||
let add_param_attrs = |item: Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
|
||||||
param| {
|
|
||||||
let attrs = RawAttrs::new(self.db.upcast(), ¶m, body_ctx.span_map());
|
|
||||||
debug_assert!(self.generic_param_attr_buffer.insert(item, attrs).is_none());
|
|
||||||
};
|
|
||||||
body_ctx.take_impl_traits_bounds();
|
body_ctx.take_impl_traits_bounds();
|
||||||
let mut generics = GenericParamsCollector::default();
|
let mut generics = GenericParamsCollector::default();
|
||||||
|
|
||||||
|
@ -892,16 +891,19 @@ impl<'a> Ctx<'a> {
|
||||||
);
|
);
|
||||||
// add super traits as bounds on Self
|
// add super traits as bounds on Self
|
||||||
// i.e., `trait Foo: Bar` is equivalent to `trait Foo where Self: Bar`
|
// i.e., `trait Foo: Bar` is equivalent to `trait Foo where Self: Bar`
|
||||||
generics.fill_bounds(
|
let bound_target = Either::Left(body_ctx.alloc_type_ref_desugared(TypeRef::Path(
|
||||||
&body_ctx,
|
Name::new_symbol_root(sym::Self_.clone()).into(),
|
||||||
bounds,
|
)));
|
||||||
Either::Left(body_ctx.alloc_type_ref_desugared(TypeRef::Path(
|
generics.fill_bounds(&mut body_ctx, bounds, bound_target);
|
||||||
Name::new_symbol_root(sym::Self_.clone()).into(),
|
|
||||||
))),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generics.fill(&body_ctx, node, add_param_attrs);
|
let span_map = body_ctx.span_map().clone();
|
||||||
|
let add_param_attrs = |item: Either<LocalTypeOrConstParamId, LocalLifetimeParamId>,
|
||||||
|
param| {
|
||||||
|
let attrs = RawAttrs::new(self.db.upcast(), ¶m, span_map.as_ref());
|
||||||
|
debug_assert!(self.generic_param_attr_buffer.insert(item, attrs).is_none());
|
||||||
|
};
|
||||||
|
generics.fill(&mut body_ctx, node, add_param_attrs);
|
||||||
|
|
||||||
let generics = generics.finish(types_map, &mut types_source_map);
|
let generics = generics.finish(types_map, &mut types_source_map);
|
||||||
(generics, types_source_map)
|
(generics, types_source_map)
|
||||||
|
@ -910,7 +912,7 @@ impl<'a> Ctx<'a> {
|
||||||
fn lower_type_bounds(
|
fn lower_type_bounds(
|
||||||
&mut self,
|
&mut self,
|
||||||
node: &dyn ast::HasTypeBounds,
|
node: &dyn ast::HasTypeBounds,
|
||||||
body_ctx: &LowerCtx<'_>,
|
body_ctx: &mut LowerCtx<'_>,
|
||||||
) -> Box<[TypeBound]> {
|
) -> Box<[TypeBound]> {
|
||||||
match node.type_bound_list() {
|
match node.type_bound_list() {
|
||||||
Some(bound_list) => {
|
Some(bound_list) => {
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
//! Context for lowering paths.
|
//! Context for lowering paths.
|
||||||
use std::cell::{OnceCell, RefCell};
|
use std::{cell::OnceCell, mem};
|
||||||
|
|
||||||
use hir_expand::{
|
use hir_expand::{span_map::SpanMap, AstId, HirFileId, InFile};
|
||||||
span_map::{SpanMap, SpanMapRef},
|
|
||||||
AstId, HirFileId, InFile,
|
|
||||||
};
|
|
||||||
use span::{AstIdMap, AstIdNode};
|
use span::{AstIdMap, AstIdNode};
|
||||||
use stdx::thin_vec::ThinVec;
|
use stdx::thin_vec::ThinVec;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -21,28 +18,11 @@ pub struct LowerCtx<'a> {
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
span_map: OnceCell<SpanMap>,
|
span_map: OnceCell<SpanMap>,
|
||||||
ast_id_map: OnceCell<Arc<AstIdMap>>,
|
ast_id_map: OnceCell<Arc<AstIdMap>>,
|
||||||
impl_trait_bounds: RefCell<Vec<ThinVec<TypeBound>>>,
|
impl_trait_bounds: Vec<ThinVec<TypeBound>>,
|
||||||
// Prevent nested impl traits like `impl Foo<impl Bar>`.
|
// Prevent nested impl traits like `impl Foo<impl Bar>`.
|
||||||
outer_impl_trait: RefCell<bool>,
|
outer_impl_trait: bool,
|
||||||
types_map: RefCell<(&'a mut TypesMap, &'a mut TypesSourceMap)>,
|
types_map: &'a mut TypesMap,
|
||||||
}
|
types_source_map: &'a mut TypesSourceMap,
|
||||||
|
|
||||||
pub(crate) struct OuterImplTraitGuard<'a, 'b> {
|
|
||||||
ctx: &'a LowerCtx<'b>,
|
|
||||||
old: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b> OuterImplTraitGuard<'a, 'b> {
|
|
||||||
fn new(ctx: &'a LowerCtx<'b>, impl_trait: bool) -> Self {
|
|
||||||
let old = ctx.outer_impl_trait.replace(impl_trait);
|
|
||||||
Self { ctx, old }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for OuterImplTraitGuard<'_, '_> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.ctx.outer_impl_trait.replace(self.old);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LowerCtx<'a> {
|
impl<'a> LowerCtx<'a> {
|
||||||
|
@ -57,9 +37,10 @@ impl<'a> LowerCtx<'a> {
|
||||||
file_id,
|
file_id,
|
||||||
span_map: OnceCell::new(),
|
span_map: OnceCell::new(),
|
||||||
ast_id_map: OnceCell::new(),
|
ast_id_map: OnceCell::new(),
|
||||||
impl_trait_bounds: RefCell::new(Vec::new()),
|
impl_trait_bounds: Vec::new(),
|
||||||
outer_impl_trait: RefCell::default(),
|
outer_impl_trait: false,
|
||||||
types_map: RefCell::new((types_map, types_source_map)),
|
types_map,
|
||||||
|
types_source_map,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,17 +56,18 @@ impl<'a> LowerCtx<'a> {
|
||||||
file_id,
|
file_id,
|
||||||
span_map,
|
span_map,
|
||||||
ast_id_map: OnceCell::new(),
|
ast_id_map: OnceCell::new(),
|
||||||
impl_trait_bounds: RefCell::new(Vec::new()),
|
impl_trait_bounds: Vec::new(),
|
||||||
outer_impl_trait: RefCell::default(),
|
outer_impl_trait: false,
|
||||||
types_map: RefCell::new((types_map, types_source_map)),
|
types_map,
|
||||||
|
types_source_map,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn span_map(&self) -> SpanMapRef<'_> {
|
pub(crate) fn span_map(&self) -> &SpanMap {
|
||||||
self.span_map.get_or_init(|| self.db.span_map(self.file_id)).as_ref()
|
self.span_map.get_or_init(|| self.db.span_map(self.file_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lower_path(&self, ast: ast::Path) -> Option<Path> {
|
pub(crate) fn lower_path(&mut self, ast: ast::Path) -> Option<Path> {
|
||||||
Path::from_src(self, ast)
|
Path::from_src(self, ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,44 +78,44 @@ impl<'a> LowerCtx<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_impl_traits_bounds(&self, bounds: ThinVec<TypeBound>) {
|
pub fn update_impl_traits_bounds_from_type_ref(&mut self, type_ref: TypeRefId) {
|
||||||
self.impl_trait_bounds.borrow_mut().push(bounds);
|
TypeRef::walk(type_ref, self.types_map, &mut |tr| {
|
||||||
|
if let TypeRef::ImplTrait(bounds) = tr {
|
||||||
|
self.impl_trait_bounds.push(bounds.clone());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_impl_traits_bounds(&self) -> Vec<ThinVec<TypeBound>> {
|
pub fn take_impl_traits_bounds(&mut self) -> Vec<ThinVec<TypeBound>> {
|
||||||
self.impl_trait_bounds.take()
|
mem::take(&mut self.impl_trait_bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn outer_impl_trait(&self) -> bool {
|
pub(crate) fn outer_impl_trait(&self) -> bool {
|
||||||
*self.outer_impl_trait.borrow()
|
self.outer_impl_trait
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn outer_impl_trait_scope<'b>(
|
pub(crate) fn with_outer_impl_trait_scope<R>(
|
||||||
&'b self,
|
&mut self,
|
||||||
impl_trait: bool,
|
impl_trait: bool,
|
||||||
) -> OuterImplTraitGuard<'b, 'a> {
|
f: impl FnOnce(&mut Self) -> R,
|
||||||
OuterImplTraitGuard::new(self, impl_trait)
|
) -> R {
|
||||||
|
let old = mem::replace(&mut self.outer_impl_trait, impl_trait);
|
||||||
|
let result = f(self);
|
||||||
|
self.outer_impl_trait = old;
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn alloc_type_ref(&self, type_ref: TypeRef, node: TypePtr) -> TypeRefId {
|
pub(crate) fn alloc_type_ref(&mut self, type_ref: TypeRef, node: TypePtr) -> TypeRefId {
|
||||||
let mut types_map = self.types_map.borrow_mut();
|
let id = self.types_map.types.alloc(type_ref);
|
||||||
let (types_map, types_source_map) = &mut *types_map;
|
self.types_source_map.types_map_back.insert(id, InFile::new(self.file_id, node));
|
||||||
let id = types_map.types.alloc(type_ref);
|
|
||||||
types_source_map.types_map_back.insert(id, InFile::new(self.file_id, node));
|
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn alloc_type_ref_desugared(&self, type_ref: TypeRef) -> TypeRefId {
|
pub(crate) fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
|
||||||
self.types_map.borrow_mut().0.types.alloc(type_ref)
|
self.types_map.types.alloc(type_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn alloc_error_type(&self) -> TypeRefId {
|
pub(crate) fn alloc_error_type(&mut self) -> TypeRefId {
|
||||||
self.types_map.borrow_mut().0.types.alloc(TypeRef::Error)
|
self.types_map.types.alloc(TypeRef::Error)
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: If we alloc while holding this, well... Bad Things will happen. Need to change this
|
|
||||||
// to use proper mutability instead of interior mutability.
|
|
||||||
pub(crate) fn types_map(&self) -> std::cell::Ref<'_, TypesMap> {
|
|
||||||
std::cell::Ref::map(self.types_map.borrow(), |it| &*it.0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ pub enum GenericArg {
|
||||||
impl Path {
|
impl Path {
|
||||||
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
||||||
/// It correctly handles `$crate` based path from macro call.
|
/// It correctly handles `$crate` based path from macro call.
|
||||||
pub fn from_src(ctx: &LowerCtx<'_>, path: ast::Path) -> Option<Path> {
|
pub fn from_src(ctx: &mut LowerCtx<'_>, path: ast::Path) -> Option<Path> {
|
||||||
lower::lower_path(ctx, path)
|
lower::lower_path(ctx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ impl<'a> PathSegments<'a> {
|
||||||
|
|
||||||
impl GenericArgs {
|
impl GenericArgs {
|
||||||
pub(crate) fn from_ast(
|
pub(crate) fn from_ast(
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
node: ast::GenericArgList,
|
node: ast::GenericArgList,
|
||||||
) -> Option<GenericArgs> {
|
) -> Option<GenericArgs> {
|
||||||
lower::lower_generic_args(lower_ctx, node)
|
lower::lower_generic_args(lower_ctx, node)
|
||||||
|
|
|
@ -19,12 +19,11 @@ use crate::{
|
||||||
|
|
||||||
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
/// Converts an `ast::Path` to `Path`. Works with use trees.
|
||||||
/// It correctly handles `$crate` based path from macro call.
|
/// It correctly handles `$crate` based path from macro call.
|
||||||
pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path> {
|
pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<Path> {
|
||||||
let mut kind = PathKind::Plain;
|
let mut kind = PathKind::Plain;
|
||||||
let mut type_anchor = None;
|
let mut type_anchor = None;
|
||||||
let mut segments = Vec::new();
|
let mut segments = Vec::new();
|
||||||
let mut generic_args = Vec::new();
|
let mut generic_args = Vec::new();
|
||||||
let span_map = ctx.span_map();
|
|
||||||
loop {
|
loop {
|
||||||
let segment = path.segment()?;
|
let segment = path.segment()?;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
|
||||||
if name_ref.text() == "$crate" {
|
if name_ref.text() == "$crate" {
|
||||||
break kind = resolve_crate_root(
|
break kind = resolve_crate_root(
|
||||||
ctx.db.upcast(),
|
ctx.db.upcast(),
|
||||||
span_map.span_for_range(name_ref.syntax().text_range()).ctx,
|
ctx.span_map().span_for_range(name_ref.syntax().text_range()).ctx,
|
||||||
)
|
)
|
||||||
.map(PathKind::DollarCrate)
|
.map(PathKind::DollarCrate)
|
||||||
.unwrap_or(PathKind::Crate);
|
.unwrap_or(PathKind::Crate);
|
||||||
|
@ -151,7 +150,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
|
||||||
// We follow what it did anyway :)
|
// We follow what it did anyway :)
|
||||||
if segments.len() == 1 && kind == PathKind::Plain {
|
if segments.len() == 1 && kind == PathKind::Plain {
|
||||||
if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
|
if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) {
|
||||||
let syn_ctxt = span_map.span_for_range(path.segment()?.syntax().text_range()).ctx;
|
let syn_ctxt = ctx.span_map().span_for_range(path.segment()?.syntax().text_range()).ctx;
|
||||||
if let Some(macro_call_id) = ctx.db.lookup_intern_syntax_context(syn_ctxt).outer_expn {
|
if let Some(macro_call_id) = ctx.db.lookup_intern_syntax_context(syn_ctxt).outer_expn {
|
||||||
if ctx.db.lookup_intern_macro_call(macro_call_id).def.local_inner {
|
if ctx.db.lookup_intern_macro_call(macro_call_id).def.local_inner {
|
||||||
kind = match resolve_crate_root(ctx.db.upcast(), syn_ctxt) {
|
kind = match resolve_crate_root(ctx.db.upcast(), syn_ctxt) {
|
||||||
|
@ -183,7 +182,7 @@ pub(super) fn lower_path(ctx: &LowerCtx<'_>, mut path: ast::Path) -> Option<Path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn lower_generic_args(
|
pub(super) fn lower_generic_args(
|
||||||
lower_ctx: &LowerCtx<'_>,
|
lower_ctx: &mut LowerCtx<'_>,
|
||||||
node: ast::GenericArgList,
|
node: ast::GenericArgList,
|
||||||
) -> Option<GenericArgs> {
|
) -> Option<GenericArgs> {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
@ -192,13 +191,7 @@ pub(super) fn lower_generic_args(
|
||||||
match generic_arg {
|
match generic_arg {
|
||||||
ast::GenericArg::TypeArg(type_arg) => {
|
ast::GenericArg::TypeArg(type_arg) => {
|
||||||
let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
|
let type_ref = TypeRef::from_ast_opt(lower_ctx, type_arg.ty());
|
||||||
let types_map = lower_ctx.types_map();
|
lower_ctx.update_impl_traits_bounds_from_type_ref(type_ref);
|
||||||
TypeRef::walk(type_ref, &types_map, &mut |tr| {
|
|
||||||
if let TypeRef::ImplTrait(bounds) = tr {
|
|
||||||
lower_ctx.update_impl_traits_bounds(bounds.clone());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
drop(types_map);
|
|
||||||
args.push(GenericArg::Type(type_ref));
|
args.push(GenericArg::Type(type_ref));
|
||||||
}
|
}
|
||||||
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
|
ast::GenericArg::AssocTypeArg(assoc_type_arg) => {
|
||||||
|
@ -208,27 +201,22 @@ pub(super) fn lower_generic_args(
|
||||||
}
|
}
|
||||||
if let Some(name_ref) = assoc_type_arg.name_ref() {
|
if let Some(name_ref) = assoc_type_arg.name_ref() {
|
||||||
// Nested impl traits like `impl Foo<Assoc = impl Bar>` are allowed
|
// Nested impl traits like `impl Foo<Assoc = impl Bar>` are allowed
|
||||||
let _guard = lower_ctx.outer_impl_trait_scope(false);
|
lower_ctx.with_outer_impl_trait_scope(false, |lower_ctx| {
|
||||||
let name = name_ref.as_name();
|
let name = name_ref.as_name();
|
||||||
let args = assoc_type_arg
|
let args = assoc_type_arg
|
||||||
.generic_arg_list()
|
.generic_arg_list()
|
||||||
.and_then(|args| lower_generic_args(lower_ctx, args));
|
.and_then(|args| lower_generic_args(lower_ctx, args));
|
||||||
let type_ref = assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
|
let type_ref =
|
||||||
let type_ref = type_ref.inspect(|&tr| {
|
assoc_type_arg.ty().map(|it| TypeRef::from_ast(lower_ctx, it));
|
||||||
let types_map = lower_ctx.types_map();
|
let type_ref = type_ref
|
||||||
TypeRef::walk(tr, &types_map, &mut |tr| {
|
.inspect(|&tr| lower_ctx.update_impl_traits_bounds_from_type_ref(tr));
|
||||||
if let TypeRef::ImplTrait(bounds) = tr {
|
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
|
||||||
lower_ctx.update_impl_traits_bounds(bounds.clone());
|
l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
|
||||||
}
|
} else {
|
||||||
});
|
Box::default()
|
||||||
drop(types_map);
|
};
|
||||||
|
bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
|
||||||
});
|
});
|
||||||
let bounds = if let Some(l) = assoc_type_arg.type_bound_list() {
|
|
||||||
l.bounds().map(|it| TypeBound::from_ast(lower_ctx, it)).collect()
|
|
||||||
} else {
|
|
||||||
Box::default()
|
|
||||||
};
|
|
||||||
bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::GenericArg::LifetimeArg(lifetime_arg) => {
|
ast::GenericArg::LifetimeArg(lifetime_arg) => {
|
||||||
|
@ -258,7 +246,7 @@ pub(super) fn lower_generic_args(
|
||||||
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
|
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
|
||||||
/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
|
/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
|
||||||
fn lower_generic_args_from_fn_path(
|
fn lower_generic_args_from_fn_path(
|
||||||
ctx: &LowerCtx<'_>,
|
ctx: &mut LowerCtx<'_>,
|
||||||
params: Option<ast::ParamList>,
|
params: Option<ast::ParamList>,
|
||||||
ret_type: Option<ast::RetType>,
|
ret_type: Option<ast::RetType>,
|
||||||
) -> Option<GenericArgs> {
|
) -> Option<GenericArgs> {
|
||||||
|
|
|
@ -2033,7 +2033,7 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
||||||
TypeRef::Macro(macro_call) => {
|
TypeRef::Macro(macro_call) => {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx = hir_def::lower::LowerCtx::new(
|
let mut ctx = hir_def::lower::LowerCtx::new(
|
||||||
f.db.upcast(),
|
f.db.upcast(),
|
||||||
macro_call.file_id,
|
macro_call.file_id,
|
||||||
&mut types_map,
|
&mut types_map,
|
||||||
|
@ -2041,7 +2041,7 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
||||||
);
|
);
|
||||||
let macro_call = macro_call.to_node(f.db.upcast());
|
let macro_call = macro_call.to_node(f.db.upcast());
|
||||||
match macro_call.path() {
|
match macro_call.path() {
|
||||||
Some(path) => match Path::from_src(&ctx, path) {
|
Some(path) => match Path::from_src(&mut ctx, path) {
|
||||||
Some(path) => path.hir_fmt(f, &types_map)?,
|
Some(path) => path.hir_fmt(f, &types_map)?,
|
||||||
None => write!(f, "{{macro}}")?,
|
None => write!(f, "{{macro}}")?,
|
||||||
},
|
},
|
||||||
|
|
|
@ -465,13 +465,13 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
|
|
||||||
let ctx = expander.ctx(
|
let mut ctx = expander.ctx(
|
||||||
self.db.upcast(),
|
self.db.upcast(),
|
||||||
&mut types_map,
|
&mut types_map,
|
||||||
&mut types_source_map,
|
&mut types_source_map,
|
||||||
);
|
);
|
||||||
// FIXME: Report syntax errors in expansion here
|
// FIXME: Report syntax errors in expansion here
|
||||||
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
|
let type_ref = TypeRef::from_ast(&mut ctx, expanded.tree());
|
||||||
|
|
||||||
drop(expander);
|
drop(expander);
|
||||||
|
|
||||||
|
|
|
@ -1271,9 +1271,9 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
let analyze = self.analyze(ty.syntax())?;
|
let analyze = self.analyze(ty.syntax())?;
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx =
|
let mut ctx =
|
||||||
LowerCtx::new(self.db.upcast(), analyze.file_id, &mut types_map, &mut types_source_map);
|
LowerCtx::new(self.db.upcast(), analyze.file_id, &mut types_map, &mut types_source_map);
|
||||||
let type_ref = crate::TypeRef::from_ast(&ctx, ty.clone());
|
let type_ref = crate::TypeRef::from_ast(&mut ctx, ty.clone());
|
||||||
let ty = hir_ty::TyLoweringContext::new_maybe_unowned(
|
let ty = hir_ty::TyLoweringContext::new_maybe_unowned(
|
||||||
self.db,
|
self.db,
|
||||||
&analyze.resolver,
|
&analyze.resolver,
|
||||||
|
@ -1289,9 +1289,9 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
let analyze = self.analyze(path.syntax())?;
|
let analyze = self.analyze(path.syntax())?;
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx =
|
let mut ctx =
|
||||||
LowerCtx::new(self.db.upcast(), analyze.file_id, &mut types_map, &mut types_source_map);
|
LowerCtx::new(self.db.upcast(), analyze.file_id, &mut types_map, &mut types_source_map);
|
||||||
let hir_path = Path::from_src(&ctx, path.clone())?;
|
let hir_path = Path::from_src(&mut ctx, path.clone())?;
|
||||||
match analyze.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), &hir_path)? {
|
match analyze.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), &hir_path)? {
|
||||||
TypeNs::TraitId(id) => Some(Trait { id }),
|
TypeNs::TraitId(id) => Some(Trait { id }),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -1974,9 +1974,9 @@ impl SemanticsScope<'_> {
|
||||||
pub fn speculative_resolve(&self, ast_path: &ast::Path) -> Option<PathResolution> {
|
pub fn speculative_resolve(&self, ast_path: &ast::Path) -> Option<PathResolution> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx =
|
let mut ctx =
|
||||||
LowerCtx::new(self.db.upcast(), self.file_id, &mut types_map, &mut types_source_map);
|
LowerCtx::new(self.db.upcast(), self.file_id, &mut types_map, &mut types_source_map);
|
||||||
let path = Path::from_src(&ctx, ast_path.clone())?;
|
let path = Path::from_src(&mut ctx, ast_path.clone())?;
|
||||||
resolve_hir_path(
|
resolve_hir_path(
|
||||||
self.db,
|
self.db,
|
||||||
&self.resolver,
|
&self.resolver,
|
||||||
|
|
|
@ -616,9 +616,9 @@ impl SourceAnalyzer {
|
||||||
) -> Option<Macro> {
|
) -> Option<Macro> {
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx =
|
let mut ctx =
|
||||||
LowerCtx::new(db.upcast(), macro_call.file_id, &mut types_map, &mut types_source_map);
|
LowerCtx::new(db.upcast(), macro_call.file_id, &mut types_map, &mut types_source_map);
|
||||||
let path = macro_call.value.path().and_then(|ast| Path::from_src(&ctx, ast))?;
|
let path = macro_call.value.path().and_then(|ast| Path::from_src(&mut ctx, ast))?;
|
||||||
self.resolver
|
self.resolver
|
||||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
|
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
|
||||||
.map(|(it, _)| it.into())
|
.map(|(it, _)| it.into())
|
||||||
|
@ -731,8 +731,9 @@ impl SourceAnalyzer {
|
||||||
|
|
||||||
let (mut types_map, mut types_source_map) =
|
let (mut types_map, mut types_source_map) =
|
||||||
(TypesMap::default(), TypesSourceMap::default());
|
(TypesMap::default(), TypesSourceMap::default());
|
||||||
let ctx = LowerCtx::new(db.upcast(), self.file_id, &mut types_map, &mut types_source_map);
|
let mut ctx =
|
||||||
let hir_path = Path::from_src(&ctx, path.clone())?;
|
LowerCtx::new(db.upcast(), self.file_id, &mut types_map, &mut types_source_map);
|
||||||
|
let hir_path = Path::from_src(&mut ctx, path.clone())?;
|
||||||
|
|
||||||
// Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
|
// Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
|
||||||
// trying to resolve foo::bar.
|
// trying to resolve foo::bar.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue