diff --git a/rust/extractor/src/crate_graph.rs b/rust/extractor/src/crate_graph.rs index 88802e6239b6..0203e8adc47d 100644 --- a/rust/extractor/src/crate_graph.rs +++ b/rust/extractor/src/crate_graph.rs @@ -2,34 +2,41 @@ use crate::{ generated::{self}, trap::{self, TrapFile}, }; +use chalk_ir::FloatTy; use chalk_ir::IntTy; use chalk_ir::Scalar; use chalk_ir::UintTy; -use chalk_ir::{FloatTy, Safety}; use itertools::Itertools; use ra_ap_base_db::{Crate, RootQueryDb}; use ra_ap_cfg::CfgAtom; use ra_ap_hir::{DefMap, ModuleDefId, PathKind, db::HirDatabase}; use ra_ap_hir::{VariantId, Visibility, db::DefDatabase}; +use ra_ap_hir_def::GenericDefId; use ra_ap_hir_def::Lookup; use ra_ap_hir_def::{ - AssocItemId, LocalModuleId, data::adt::VariantData, item_scope::ImportOrGlob, - item_tree::ImportKind, nameres::ModuleData, path::ImportAlias, + AssocItemId, ConstParamId, LocalModuleId, TypeOrConstParamId, + data::adt::VariantData, + generics::{GenericParams, TypeOrConstParamData}, + item_scope::ImportOrGlob, + item_tree::ImportKind, + nameres::ModuleData, + path::ImportAlias, }; use ra_ap_hir_def::{HasModule, visibility::VisibilityExplicitness}; use ra_ap_hir_def::{ModuleId, resolver::HasResolver}; +use ra_ap_hir_ty::GenericArg; +use ra_ap_hir_ty::ProjectionTyExt; +use ra_ap_hir_ty::TraitRefExt; use ra_ap_hir_ty::Ty; use ra_ap_hir_ty::TyExt; +use ra_ap_hir_ty::TyLoweringContext; use ra_ap_hir_ty::WhereClause; +use ra_ap_hir_ty::from_assoc_type_id; use ra_ap_hir_ty::{Binders, FnPointer}; use ra_ap_hir_ty::{Interner, ProjectionTy}; -use ra_ap_hir_ty::{TraitRefExt, from_assoc_type_id}; use ra_ap_ide_db::RootDatabase; use ra_ap_vfs::{Vfs, VfsPath}; -use ra_ap_hir_def::data::ConstFlags; -use ra_ap_hir_def::item_tree::StaticFlags; -use ra_ap_hir_ty::db::InternedCallableDefId; use std::hash::Hasher; use std::{cmp::Ordering, collections::HashMap, path::PathBuf}; use std::{hash::Hash, vec}; @@ -245,7 +252,7 @@ fn emit_reexport( name, }) }); - let path = make_qualified_path(trap, path_components); + let path = make_qualified_path(trap, path_components, None); let use_tree = trap.emit(generated::UseTree { id: trap::TrapId::Star, is_glob: false, @@ -273,7 +280,7 @@ fn emit_module_items( module: &ModuleData, trap: &mut TrapFile, ) -> Vec> { - let mut items = Vec::new(); + let mut items: Vec> = Vec::new(); let mut uses = HashMap::new(); let item_scope = &module.scope; for (name, item) in item_scope.entries() { @@ -294,18 +301,27 @@ fn emit_module_items( { match value { ModuleDefId::FunctionId(function) => { - items.extend(emit_function(db, name.as_str(), trap, function, vis)); + items.push(emit_function(db, trap, None, function, name).into()); } ModuleDefId::ConstId(konst) => { - items.extend(emit_const(db, name.as_str(), trap, konst, vis)); + items.extend( + emit_const(db, trap, None, name.as_str(), konst, vis) + .map(Into::>::into), + ); } ModuleDefId::StaticId(statik) => { items.extend(emit_static(db, name.as_str(), trap, statik, vis)); } - ModuleDefId::EnumVariantId(variant_id) => { - items.extend(emit_enum_variant(db, name.as_str(), trap, variant_id, vis)); - } - _ => (), + // Enum variants can only be introduced into the value namespace by an import (`use`) statement + ModuleDefId::EnumVariantId(_) => (), + // Not in the "value" namespace + ModuleDefId::ModuleId(_) + | ModuleDefId::AdtId(_) + | ModuleDefId::TraitId(_) + | ModuleDefId::TraitAliasId(_) + | ModuleDefId::TypeAliasId(_) + | ModuleDefId::BuiltinType(_) + | ModuleDefId::MacroId(_) => (), } } if let Some(ra_ap_hir_def::per_ns::Item { @@ -332,7 +348,21 @@ fn emit_module_items( ModuleDefId::TraitId(trait_id) => { items.extend(emit_trait(db, name.as_str(), trap, trait_id, vis)); } - _ => (), + ModuleDefId::TypeAliasId(type_alias_id_) => items.extend( + emit_type_alias(db, trap, None, name.as_str(), type_alias_id_, vis) + .map(Into::>::into), + ), + ModuleDefId::TraitAliasId(_) => (), + ModuleDefId::BuiltinType(_) => (), + // modules are handled separatedly + ModuleDefId::ModuleId(_) => (), + // Enum variants cannot be declarted, only imported + ModuleDefId::EnumVariantId(_) => (), + // Not in the "types" namespace + ModuleDefId::FunctionId(_) + | ModuleDefId::ConstId(_) + | ModuleDefId::StaticId(_) + | ModuleDefId::MacroId(_) => (), } } } @@ -342,48 +372,138 @@ fn emit_module_items( fn emit_function( db: &dyn HirDatabase, - name: &str, trap: &mut TrapFile, + container: Option, function: ra_ap_hir_def::FunctionId, - visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); - if let Some(type_) = db.value_ty(function.into()) { - items.push(const_or_function(db, name, trap, type_, visibility)); + name: &ra_ap_hir::Name, +) -> trap::Label { + let sig = db.callable_item_signature(function.into()); + let parameters = collect_generic_parameters(db, function.into(), container); + + assert_eq!(sig.binders.len(Interner), parameters.len()); + let sig = sig.skip_binders(); + let ty_vars = &[parameters]; + let params = sig + .params() + .iter() + .map(|p| { + let type_repr = emit_hir_ty(trap, db, ty_vars, p); + trap.emit(generated::Param { + id: trap::TrapId::Star, + attrs: vec![], + type_repr, + pat: None, + }) + }) + .collect(); + + let ret_type = emit_hir_ty(trap, db, ty_vars, sig.ret()); + let param_list = trap.emit(generated::ParamList { + id: trap::TrapId::Star, + params, + self_param: None, + }); + let ret_type = ret_type.map(|ret_type| { + trap.emit(generated::RetTypeRepr { + id: trap::TrapId::Star, + type_repr: Some(ret_type), + }) + }); + let name = Some(trap.emit(generated::Name { + id: trap::TrapId::Star, + text: Some(name.as_str().to_owned()), + })); + let data = db.function_data(function); + let visibility = emit_visibility( + db, + trap, + data.visibility + .resolve(db.upcast(), &function.resolver(db.upcast())), + ); + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, function.into()); + trap.emit(generated::Function { + id: trap::TrapId::Star, + name, + attrs: vec![], + body: None, + is_const: data.is_const(), + is_default: data.is_default(), + visibility, + abi: None, + is_async: data.is_async(), + is_gen: false, + is_unsafe: data.is_unsafe(), + generic_param_list, + param_list: Some(param_list), + ret_type, + where_clause: None, + }) +} + +fn collect_generic_parameters( + db: &dyn HirDatabase, + def: GenericDefId, + container: Option, +) -> Vec { + let mut parameters = Vec::new(); + let gen_params = db.generic_params(def); + collect(&gen_params, &mut parameters); + if let Some(gen_params) = container.map(|container| db.generic_params(container)) { + collect(gen_params.as_ref(), &mut parameters); + } + return parameters; + + fn collect(gen_params: &GenericParams, parameters: &mut Vec) { + // Self, Lifetimes, TypesOrConsts + let skip = if gen_params.trait_self_param().is_some() { + parameters.push("Self".into()); + 1 + } else { + 0 + }; + parameters.extend(gen_params.iter_lt().map(|(_, lt)| lt.name.as_str().into())); + parameters.extend(gen_params.iter_type_or_consts().skip(skip).map(|(_, p)| { + p.name() + .map(|p| p.as_str().into()) + .unwrap_or("{error}".into()) + })); } - items } fn emit_const( db: &dyn HirDatabase, - name: &str, trap: &mut TrapFile, + container: Option, + name: &str, konst: ra_ap_hir_def::ConstId, visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); +) -> Option> { let type_ = db.value_ty(konst.into()); - let type_repr = type_.and_then(|type_| emit_hir_ty(trap, db, type_.skip_binders())); + let parameters = collect_generic_parameters(db, konst.into(), container); + assert_eq!( + type_ + .as_ref() + .map_or(0, |type_| type_.binders.len(Interner)), + parameters.len() + ); + let ty_vars = &[parameters]; + let type_repr = type_.and_then(|type_| emit_hir_ty(trap, db, ty_vars, type_.skip_binders())); let name = Some(trap.emit(generated::Name { id: trap::TrapId::Star, text: Some(name.to_owned()), })); let konst = db.const_data(konst); let visibility = emit_visibility(db, trap, visibility); - items.push( - trap.emit(generated::Const { - id: trap::TrapId::Star, - name, - attrs: vec![], - body: None, - is_const: true, - is_default: konst.flags.contains(ConstFlags::HAS_BODY), - type_repr, - visibility, - }) - .into(), - ); - items + Some(trap.emit(generated::Const { + id: trap::TrapId::Star, + name, + attrs: vec![], + body: None, + is_const: true, + is_default: konst.has_body(), + type_repr, + visibility, + })) } fn emit_static( @@ -392,17 +512,24 @@ fn emit_static( trap: &mut TrapFile, statik: ra_ap_hir_def::StaticId, visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); +) -> Option> { let type_ = db.value_ty(statik.into()); - let type_repr = type_.and_then(|type_| emit_hir_ty(trap, db, type_.skip_binders())); + let parameters = collect_generic_parameters(db, statik.into(), None); + assert_eq!( + type_ + .as_ref() + .map_or(0, |type_| type_.binders.len(Interner)), + parameters.len() + ); + let ty_vars = &[parameters]; + let type_repr = type_.and_then(|type_| emit_hir_ty(trap, db, ty_vars, type_.skip_binders())); let name = Some(trap.emit(generated::Name { id: trap::TrapId::Star, text: Some(name.to_owned()), })); let statik = db.static_data(statik); let visibility = emit_visibility(db, trap, visibility); - items.push( + Some( trap.emit(generated::Static { id: trap::TrapId::Star, name, @@ -410,57 +537,171 @@ fn emit_static( body: None, type_repr, visibility, - is_mut: statik.flags.contains(StaticFlags::MUTABLE), + is_mut: statik.mutable(), is_static: true, - is_unsafe: statik.flags.contains(StaticFlags::HAS_UNSAFE_KW), + is_unsafe: statik.has_unsafe_kw(), }) .into(), - ); - items + ) } -fn emit_enum_variant( +fn emit_type_alias( db: &dyn HirDatabase, - name: &str, trap: &mut TrapFile, - variant_id: ra_ap_hir_def::EnumVariantId, + container: Option, + name: &str, + alias_id: ra_ap_hir_def::TypeAliasId, visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); - if let Some(type_) = db.value_ty(variant_id.into()) { - items.push(const_or_function(db, name, trap, type_, visibility)); - } - items +) -> Option> { + let (type_, _) = db.type_for_type_alias_with_diagnostics(alias_id); + let parameters = collect_generic_parameters(db, alias_id.into(), container); + assert_eq!(type_.binders.len(Interner), parameters.len()); + let ty_vars = &[parameters]; + let type_repr = emit_hir_ty(trap, db, ty_vars, type_.skip_binders()); + let name = Some(trap.emit(generated::Name { + id: trap::TrapId::Star, + text: Some(name.to_owned()), + })); + let visibility = emit_visibility(db, trap, visibility); + let alias = db.type_alias_data(alias_id); + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, alias_id.into()); + Some(trap.emit(generated::TypeAlias { + id: trap::TrapId::Star, + name, + attrs: vec![], + is_default: container.is_some() && alias.type_ref.is_some(), + type_repr, + visibility, + generic_param_list, + type_bound_list: None, + where_clause: None, + })) } +fn emit_generic_param_list( + trap: &mut TrapFile, + db: &dyn HirDatabase, + ty_vars: &[Vec], + def: GenericDefId, +) -> Option> { + let params = db.generic_params(def); + let trait_self_param = params.trait_self_param(); + if params.is_empty() || params.len() == 1 && trait_self_param.is_some() { + return None; + } + let mut generic_params = Vec::new(); + generic_params.extend(params.iter_lt().map( + |(_, param)| -> trap::Label { + let lifetime = trap + .emit(generated::Lifetime { + id: trap::TrapId::Star, + text: Some(param.name.as_str().to_owned()), + }) + .into(); + + trap.emit(generated::LifetimeParam { + id: trap::TrapId::Star, + attrs: vec![], + lifetime, + type_bound_list: None, + }) + .into() + }, + )); + generic_params.extend( + params + .iter_type_or_consts() + .filter(|(id, _)| trait_self_param != Some(*id)) + .map( + |(param_id, param)| -> trap::Label { + match param { + TypeOrConstParamData::TypeParamData(param) => { + let name = Some(trap.emit(generated::Name { + id: trap::TrapId::Star, + text: param.name.as_ref().map(|name| name.as_str().to_owned()), + })); + let resolver = def.resolver(db.upcast()); + let mut ctx = TyLoweringContext::new( + db, + &resolver, + ¶ms.types_map, + def.into(), + ); + + let default_type = param + .default + .and_then(|ty| emit_hir_ty(trap, db, ty_vars, &ctx.lower_ty(ty))); + trap.emit(generated::TypeParam { + id: trap::TrapId::Star, + attrs: vec![], + name, + default_type, + type_bound_list: None, + }) + .into() + } + TypeOrConstParamData::ConstParamData(param) => { + let name = Some(trap.emit(generated::Name { + id: trap::TrapId::Star, + text: param.name.as_str().to_owned().into(), + })); + let param_id = TypeOrConstParamId { + parent: def, + local_id: param_id, + }; + let ty = db.const_param_ty(ConstParamId::from_unchecked(param_id)); + let type_repr = emit_hir_ty(trap, db, ty_vars, &ty); + trap.emit(generated::ConstParam { + id: trap::TrapId::Star, + attrs: vec![], + name, + default_val: None, + is_const: true, + type_repr, + }) + .into() + } + } + }, + ), + ); + trap.emit(generated::GenericParamList { + id: trap::TrapId::Star, + generic_params, + }) + .into() +} fn emit_adt( db: &dyn HirDatabase, name: &str, trap: &mut TrapFile, adt_id: ra_ap_hir_def::AdtId, visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); +) -> Option> { + let parameters = collect_generic_parameters(db, adt_id.into(), None); + let ty_vars = &[parameters]; + match adt_id { ra_ap_hir_def::AdtId::StructId(struct_id) => { let name = Some(trap.emit(generated::Name { id: trap::TrapId::Star, text: Some(name.to_owned()), })); - let field_list = emit_variant_data(trap, db, struct_id.into()).into(); + let field_list = emit_variant_data(trap, db, ty_vars, struct_id.into()).into(); let visibility = emit_visibility(db, trap, visibility); - items.push( + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, adt_id.into()); + Some( trap.emit(generated::Struct { id: trap::TrapId::Star, name, attrs: vec![], field_list, - generic_param_list: None, + generic_param_list, visibility, where_clause: None, }) .into(), - ); + ) } ra_ap_hir_def::AdtId::EnumId(enum_id) => { let data = db.enum_variants(enum_id); @@ -472,7 +713,7 @@ fn emit_adt( id: trap::TrapId::Star, text: Some(name.as_str().to_owned()), })); - let field_list = emit_variant_data(trap, db, (*enum_id).into()).into(); + let field_list = emit_variant_data(trap, db, ty_vars, (*enum_id).into()).into(); let visibility = None; trap.emit(generated::Variant { id: trap::TrapId::Star, @@ -493,41 +734,42 @@ fn emit_adt( text: Some(name.to_owned()), })); let visibility = emit_visibility(db, trap, visibility); - items.push( + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, adt_id.into()); + Some( trap.emit(generated::Enum { id: trap::TrapId::Star, name, attrs: vec![], - generic_param_list: None, + generic_param_list, variant_list, visibility, where_clause: None, }) .into(), - ); + ) } ra_ap_hir_def::AdtId::UnionId(union_id) => { let name = Some(trap.emit(generated::Name { id: trap::TrapId::Star, text: Some(name.to_owned()), })); - let struct_field_list = emit_variant_data(trap, db, union_id.into()).into(); + let struct_field_list = emit_variant_data(trap, db, ty_vars, union_id.into()).into(); let visibility = emit_visibility(db, trap, visibility); - items.push( + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, adt_id.into()); + Some( trap.emit(generated::Union { id: trap::TrapId::Star, name, attrs: vec![], struct_field_list, - generic_param_list: None, + generic_param_list, visibility, where_clause: None, }) .into(), - ); + ) } } - items } fn emit_trait( @@ -536,70 +778,36 @@ fn emit_trait( trap: &mut TrapFile, trait_id: ra_ap_hir_def::TraitId, visibility: Visibility, -) -> Vec> { - let mut items = Vec::new(); - let data = db.trait_items(trait_id); - let assoc_items: Vec> = data +) -> Option> { + let parameters = collect_generic_parameters(db, trait_id.into(), None); + let ty_vars = &[parameters]; + let trait_items = db.trait_items(trait_id); + let assoc_items: Vec> = trait_items .items .iter() - .flat_map(|(name, item)| { - if let AssocItemId::FunctionId(function) = item { - let sig = db.callable_item_signature((*function).into()); - let sig = sig.skip_binders(); - let params = sig - .params() - .iter() - .map(|p| { - let type_repr = emit_hir_ty(trap, db, p); - trap.emit(generated::Param { - id: trap::TrapId::Star, - attrs: vec![], - type_repr, - pat: None, - }) - }) - .collect(); - - let ret_type = emit_hir_ty(trap, db, sig.ret()); - let param_list = trap.emit(generated::ParamList { - id: trap::TrapId::Star, - params, - self_param: None, - }); - let ret_type = ret_type.map(|ret_type| { - trap.emit(generated::RetTypeRepr { - id: trap::TrapId::Star, - type_repr: Some(ret_type), - }) - }); - let name = Some(trap.emit(generated::Name { - id: trap::TrapId::Star, - text: Some(name.as_str().to_owned()), - })); - let visibility = emit_visibility(db, trap, visibility); - Some( - trap.emit(generated::Function { - id: trap::TrapId::Star, - name, - attrs: vec![], - body: None, - is_const: false, - is_default: false, - visibility, - abi: None, - is_async: false, - is_gen: false, - is_unsafe: matches!(sig.to_fn_ptr().sig.safety, Safety::Unsafe), - generic_param_list: None, //TODO - param_list: Some(param_list), - ret_type, - where_clause: None, - }) - .into(), - ) - } else { - None + .flat_map(|(name, item)| match item { + AssocItemId::FunctionId(function_id) => { + Some(emit_function(db, trap, Some(trait_id.into()), *function_id, name).into()) } + + AssocItemId::ConstId(const_id) => emit_const( + db, + trap, + Some(trait_id.into()), + name.as_str(), + *const_id, + visibility, + ) + .map(Into::into), + AssocItemId::TypeAliasId(type_alias_id) => emit_type_alias( + db, + trap, + Some(trait_id.into()), + name.as_str(), + *type_alias_id, + visibility, + ) + .map(Into::into), }) .collect(); let assoc_item_list = Some(trap.emit(generated::AssocItemList { @@ -612,13 +820,14 @@ fn emit_trait( text: Some(name.to_owned()), })); let visibility = emit_visibility(db, trap, visibility); - items.push( + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, trait_id.into()); + Some( trap.emit(generated::Trait { id: trap::TrapId::Star, name, assoc_item_list, attrs: vec![], - generic_param_list: None, + generic_param_list, is_auto: false, is_unsafe: false, type_bound_list: None, @@ -626,8 +835,7 @@ fn emit_trait( where_clause: None, }) .into(), - ); - items + ) } fn emit_module_impls( @@ -638,16 +846,20 @@ fn emit_module_impls( let mut items = Vec::new(); module.scope.impls().for_each(|imp| { let self_ty = db.impl_self_ty(imp); - let self_ty = emit_hir_ty(trap, db, self_ty.skip_binders()); - let imp_data = db.impl_data(imp); - let trait_ = imp_data - .target_trait - .as_ref() - .and_then(|t| make_qualified_path(trap, emit_hir_path(&imp_data.types_map[t.path]))); - let trait_ = trait_.map(|trait_| { + let parameters = collect_generic_parameters(db, imp.into(), None); + let parameters_len = parameters.len(); + assert_eq!(self_ty.binders.len(Interner), parameters_len); + + let ty_vars = &[parameters]; + let self_ty = emit_hir_ty(trap, db, ty_vars, self_ty.skip_binders()); + let path = db.impl_trait(imp).map(|trait_ref| { + assert_eq!(trait_ref.binders.len(Interner), parameters_len); + trait_path(db, trap, ty_vars, trait_ref.skip_binders()) + }); + let trait_ = path.map(|path| { trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, - path: Some(trait_), + path, }) .into() }); @@ -657,66 +869,7 @@ fn emit_module_impls( .iter() .flat_map(|item| { if let (name, AssocItemId::FunctionId(function)) = item { - let sig = db.callable_item_signature((*function).into()); - let sig = sig.skip_binders(); - let params = sig - .params() - .iter() - .map(|p| { - let type_repr = emit_hir_ty(trap, db, p); - trap.emit(generated::Param { - id: trap::TrapId::Star, - attrs: vec![], - type_repr, - pat: None, - }) - }) - .collect(); - - let ret_type = emit_hir_ty(trap, db, sig.ret()); - let param_list = trap.emit(generated::ParamList { - id: trap::TrapId::Star, - params, - self_param: None, - }); - let ret_type = ret_type.map(|ret_type| { - trap.emit(generated::RetTypeRepr { - id: trap::TrapId::Star, - type_repr: Some(ret_type), - }) - }); - let name = Some(trap.emit(generated::Name { - id: trap::TrapId::Star, - text: Some(name.as_str().to_owned()), - })); - let data = db.function_data(*function); - let visibility = emit_visibility( - db, - trap, - data.visibility - .resolve(db.upcast(), &function.resolver(db.upcast())), - ); - - Some( - trap.emit(generated::Function { - id: trap::TrapId::Star, - name, - attrs: vec![], - body: None, - is_const: false, - is_default: false, - visibility, - abi: None, - is_async: false, - is_gen: false, - is_unsafe: matches!(sig.to_fn_ptr().sig.safety, Safety::Unsafe), - generic_param_list: None, //TODO - param_list: Some(param_list), - ret_type, - where_clause: None, - }) - .into(), - ) + Some(emit_function(db, trap, Some(imp.into()), *function, name).into()) } else { None } @@ -727,6 +880,7 @@ fn emit_module_impls( assoc_items, attrs: vec![], })); + let generic_param_list = emit_generic_param_list(trap, db, ty_vars, imp.into()); items.push( trap.emit(generated::Impl { id: trap::TrapId::Star, @@ -734,7 +888,7 @@ fn emit_module_impls( self_ty, assoc_item_list, attrs: vec![], - generic_param_list: None, + generic_param_list, is_const: false, is_default: false, is_unsafe: false, @@ -760,114 +914,32 @@ fn emit_visibility( Visibility::Module(_, VisibilityExplicitness::Implicit) => None, }; path.map(|path| { - let path = make_qualified_path(trap, path); + let path = make_qualified_path(trap, path, None); trap.emit(generated::Visibility { id: trap::TrapId::Star, path, }) }) } -fn const_or_function( - db: &dyn HirDatabase, - name: &str, - trap: &mut TrapFile, - type_: Binders, - visibility: Visibility, -) -> trap::Label { - let type_: &chalk_ir::Ty = type_.skip_binders(); - match type_.kind(ra_ap_hir_ty::Interner) { - chalk_ir::TyKind::FnDef(fn_def_id, parameters) => { - let callable_def_id = - db.lookup_intern_callable_def(InternedCallableDefId::from(*fn_def_id)); - let data = db.fn_def_datum(callable_def_id); - - let sig = ra_ap_hir_ty::CallableSig::from_def(db, *fn_def_id, parameters); - let params = sig - .params() - .iter() - .map(|p| { - let type_repr = emit_hir_ty(trap, db, p); - trap.emit(generated::Param { - id: trap::TrapId::Star, - attrs: vec![], - type_repr, - pat: None, - }) - }) - .collect(); - - let ret_type = emit_hir_ty(trap, db, sig.ret()); - let param_list = trap.emit(generated::ParamList { - id: trap::TrapId::Star, - params, - self_param: None, - }); - let ret_type = ret_type.map(|ret_type| { - trap.emit(generated::RetTypeRepr { - id: trap::TrapId::Star, - type_repr: Some(ret_type), - }) - }); - let name = Some(trap.emit(generated::Name { - id: trap::TrapId::Star, - text: Some(name.to_owned()), - })); - let visibility = emit_visibility(db, trap, visibility); - trap.emit(generated::Function { - id: trap::TrapId::Star, - name, - attrs: vec![], - body: None, - is_const: false, - is_default: false, - visibility, - abi: None, - is_async: false, - is_gen: false, - is_unsafe: matches!(data.sig.safety, Safety::Unsafe), - generic_param_list: None, //TODO - param_list: Some(param_list), - ret_type, - where_clause: None, - }) - .into() - } - _ => { - let type_repr = emit_hir_ty(trap, db, type_); - let name = Some(trap.emit(generated::Name { - id: trap::TrapId::Star, - text: Some(name.to_owned()), - })); - let visibility = emit_visibility(db, trap, visibility); - trap.emit(generated::Const { - id: trap::TrapId::Star, - name, - attrs: vec![], - body: None, - is_const: false, - is_default: false, - type_repr, - visibility, - }) - .into() - } - } +fn push_ty_vars(ty_vars: &[Vec], vars: Vec) -> Vec> { + let mut result = ty_vars.to_vec(); + result.push(vars); + result } fn emit_hir_type_bound( db: &dyn HirDatabase, trap: &mut TrapFile, + ty_vars: &[Vec], type_bound: &Binders>, ) -> Option> { + // Rust-analyzer seems to call `wrap_empty_binders` on `WhereClause`s. + let parameters = vec![]; + assert_eq!(type_bound.binders.len(Interner), parameters.len(),); + let ty_vars = &push_ty_vars(ty_vars, parameters); + match type_bound.skip_binders() { WhereClause::Implemented(trait_ref) => { - let mut path = make_path(db, trait_ref.hir_trait_id()); - path.push( - db.trait_data(trait_ref.hir_trait_id()) - .name - .as_str() - .to_owned(), - ); - let path = make_qualified_path(trap, path); + let path = trait_path(db, trap, ty_vars, trait_ref); let type_repr = Some( trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, @@ -884,28 +956,56 @@ fn emit_hir_type_bound( use_bound_generic_args: None, })) } - _ => None, + WhereClause::AliasEq(_) + | WhereClause::LifetimeOutlives(_) + | WhereClause::TypeOutlives(_) => None, // TODO } } -fn emit_hir_path(path: &ra_ap_hir_def::path::Path) -> Vec { - path.segments() - .iter() - .map(|x| x.name.as_str().to_owned()) - .collect() +fn trait_path( + db: &dyn HirDatabase, + trap: &mut TrapFile, + ty_vars: &[Vec], + trait_ref: &chalk_ir::TraitRef, +) -> Option> { + let mut path = make_path(db, trait_ref.hir_trait_id()); + path.push( + db.trait_data(trait_ref.hir_trait_id()) + .name + .as_str() + .to_owned(), + ); + let generic_arg_list = emit_generic_arg_list( + trap, + db, + ty_vars, + &trait_ref.substitution.as_slice(Interner)[1..], + ); + + make_qualified_path(trap, path, generic_arg_list) } fn emit_hir_fn_ptr( trap: &mut TrapFile, - db: &dyn HirDatabase, + ty_vars: &[Vec], function: &FnPointer, ) -> trap::Label { + // Currently rust-analyzer does not handle `for<'a'> fn()` correctly: + // ```rust + // TyKind::Function(FnPointer { + // num_binders: 0, // FIXME lower `for<'a> fn()` correctly + // ``` + // https://github.com/rust-lang/rust-analyzer/blob/c5882732e6e6e09ac75cddd13545e95860be1c42/crates/hir-ty/src/lower.rs#L325 + let parameters = vec![]; + assert_eq!(function.num_binders, parameters.len(),); + let ty_vars = &push_ty_vars(ty_vars, parameters); + let parameters: Vec<_> = function.substitution.0.type_parameters(Interner).collect(); let (ret_type, params) = parameters.split_last().unwrap(); - let ret_type = emit_hir_ty(trap, db, ret_type); + let ret_type = emit_hir_ty(trap, db, ty_vars, ret_type); let ret_type = Some(trap.emit(generated::RetTypeRepr { id: trap::TrapId::Star, type_repr: ret_type, @@ -913,7 +1013,7 @@ fn emit_hir_fn_ptr( let params = params .iter() .map(|t| { - let type_repr = emit_hir_ty(trap, db, t); + let type_repr = emit_hir_ty(trap, db, ty_vars, t); trap.emit(generated::Param { id: trap::TrapId::Star, attrs: vec![], @@ -996,14 +1096,17 @@ fn make_path_mod(db: &dyn DefDatabase, module: ModuleId) -> Vec { path.reverse(); path } + fn make_qualified_path( trap: &mut TrapFile, path: Vec, + generic_arg_list: Option>, ) -> Option> { fn qualified_path( trap: &mut TrapFile, qualifier: Option>, name: String, + generic_arg_list: Option>, ) -> trap::Label { let identifier = Some(trap.emit(generated::NameRef { id: trap::TrapId::Star, @@ -1011,7 +1114,7 @@ fn make_qualified_path( })); let segment = Some(trap.emit(generated::PathSegment { id: trap::TrapId::Star, - generic_arg_list: None, + generic_arg_list, identifier, parenthesized_arg_list: None, ret_type: None, @@ -1023,13 +1126,15 @@ fn make_qualified_path( segment, }) } + let args = std::iter::repeat_n(None, &path.len() - 1).chain(std::iter::once(generic_arg_list)); path.into_iter() - .fold(None, |q, p| Some(qualified_path(trap, q, p))) + .zip(args) + .fold(None, |q, (p, a)| Some(qualified_path(trap, q, p, a))) } fn emit_hir_ty( trap: &mut TrapFile, - db: &dyn HirDatabase, + ty_vars: &[Vec], ty: &Ty, ) -> Option> { match ty.kind(ra_ap_hir_ty::Interner) { @@ -1050,7 +1155,7 @@ fn emit_hir_ty( chalk_ir::TyKind::Tuple(_size, substitution) => { let fields = substitution.type_parameters(ra_ap_hir_ty::Interner); let fields = fields - .flat_map(|field| emit_hir_ty(trap, db, &field)) + .flat_map(|field| emit_hir_ty(trap, db, ty_vars, &field)) .collect(); Some( @@ -1062,7 +1167,7 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Raw(mutability, ty) => { - let type_repr = emit_hir_ty(trap, db, ty); + let type_repr = emit_hir_ty(trap, db, ty_vars, ty); Some( trap.emit(generated::PtrTypeRepr { @@ -1074,21 +1179,21 @@ fn emit_hir_ty( .into(), ) } - chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { - let type_repr = emit_hir_ty(trap, db, ty); - let lifetime = None; //TODO: ? + chalk_ir::TyKind::Ref(mutability, lifetime, ty) => { + let type_repr = emit_hir_ty(trap, db, ty_vars, ty); + let lifetime = emit_lifetime(trap, ty_vars, lifetime); Some( trap.emit(generated::RefTypeRepr { id: trap::TrapId::Star, is_mut: matches!(mutability, chalk_ir::Mutability::Mut), - lifetime, + lifetime: Some(lifetime), type_repr, }) .into(), ) } chalk_ir::TyKind::Array(ty, _konst) => { - let element_type_repr = emit_hir_ty(trap, db, ty); + let element_type_repr = emit_hir_ty(trap, db, ty_vars, ty); // TODO: handle array size constant Some( trap.emit(generated::ArrayTypeRepr { @@ -1100,7 +1205,7 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Slice(ty) => { - let type_repr = emit_hir_ty(trap, db, ty); + let type_repr = emit_hir_ty(trap, db, ty_vars, ty); Some( trap.emit(generated::SliceTypeRepr { id: trap::TrapId::Star, @@ -1110,7 +1215,7 @@ fn emit_hir_ty( ) } - chalk_ir::TyKind::Adt(adt_id, _substitution) => { + chalk_ir::TyKind::Adt(adt_id, substitution) => { let mut path = make_path(db, adt_id.0); let name = match adt_id.0 { ra_ap_hir_def::AdtId::StructId(struct_id) => { @@ -1124,7 +1229,9 @@ fn emit_hir_ty( } }; path.push(name); - let path = make_qualified_path(trap, path); + let generic_arg_list = + emit_generic_arg_list(trap, db, ty_vars, substitution.as_slice(Interner)); + let path = make_qualified_path(trap, path, generic_arg_list); Some( trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, @@ -1134,7 +1241,7 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Scalar(scalar) => { - let path = make_qualified_path(trap, vec![scalar_to_str(scalar).to_owned()]); + let path = make_qualified_path(trap, vec![scalar_to_str(scalar).to_owned()], None); Some( trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, @@ -1144,7 +1251,7 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Str => { - let path = make_qualified_path(trap, vec!["str".to_owned()]); + let path = make_qualified_path(trap, vec!["str".to_owned()], None); Some( trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, @@ -1154,7 +1261,7 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Function(fn_pointer) => { - Some(emit_hir_fn_ptr(trap, db, fn_pointer).into()) + Some(emit_hir_fn_ptr(trap, db, ty_vars, fn_pointer).into()) } chalk_ir::TyKind::OpaqueType(_, _) | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(_)) => { @@ -1162,7 +1269,7 @@ fn emit_hir_ty( .impl_trait_bounds(db) .iter() .flatten() - .flat_map(|t| emit_hir_type_bound(db, trap, t)) + .flat_map(|t| emit_hir_type_bound(db, trap, ty_vars, t)) .collect(); let type_bound_list = Some(trap.emit(generated::TypeBoundList { id: trap::TrapId::Star, @@ -1177,11 +1284,15 @@ fn emit_hir_ty( ) } chalk_ir::TyKind::Dyn(dyn_ty) => { + let parameters = vec!["Self".to_owned()]; + assert_eq!(dyn_ty.bounds.binders.len(Interner), parameters.len(),); + let ty_vars = &push_ty_vars(ty_vars, parameters); + let bounds = dyn_ty .bounds .skip_binders() .iter(ra_ap_hir_ty::Interner) - .flat_map(|t| emit_hir_type_bound(db, trap, t)) + .flat_map(|t| emit_hir_type_bound(db, trap, ty_vars, t)) .collect(); let type_bound_list = Some(trap.emit(generated::TypeBoundList { id: trap::TrapId::Star, @@ -1197,45 +1308,89 @@ fn emit_hir_ty( } chalk_ir::TyKind::FnDef(fn_def_id, parameters) => { let sig = ra_ap_hir_ty::CallableSig::from_def(db, *fn_def_id, parameters); - Some(emit_hir_fn_ptr(trap, db, &sig.to_fn_ptr()).into()) + Some(emit_hir_fn_ptr(trap, db, ty_vars, &sig.to_fn_ptr()).into()) } chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy { associated_ty_id, - substitution: _, + substitution, })) - | chalk_ir::TyKind::AssociatedType(associated_ty_id, _) => { - let assoc_ty_data = db.associated_ty_data(from_assoc_type_id(*associated_ty_id)); + | chalk_ir::TyKind::AssociatedType(associated_ty_id, substitution) => { + let pt = ProjectionTy { + associated_ty_id: *associated_ty_id, + substitution: substitution.clone(), + }; - let _name = db - .type_alias_data(assoc_ty_data.name) - .name - .as_str() - .to_owned(); + // >::Name<...> - let trait_ref = ra_ap_hir_ty::TraitRef { - trait_id: assoc_ty_data.trait_id, - substitution: assoc_ty_data.binders.identity_substitution(Interner), - }; - let mut trait_path = make_path(db, trait_ref.hir_trait_id()); - trait_path.push( - db.trait_data(trait_ref.hir_trait_id()) - .name - .as_str() - .to_owned(), - ); - //TODO - // trap.emit(generated::AssociatedType { - // id: trap::TrapId::Star, - // trait_path, - // name, - // }) - // .into() - None + let qualifier = trap.emit(generated::PathSegment { + id: trap::TrapId::Star, + generic_arg_list: None, + identifier: None, + parenthesized_arg_list: None, + ret_type: None, + return_type_syntax: None, + }); + let self_ty = pt.self_type_parameter(db); + let self_ty = emit_hir_ty(trap, db, ty_vars, &self_ty); + if let Some(self_ty) = self_ty { + generated::PathSegment::emit_type_repr(qualifier, self_ty, &mut trap.writer) + } + let trait_ref = pt.trait_ref(db); + let trait_ref = trait_path(db, trap, ty_vars, &trait_ref); + let trait_ref = trait_ref.map(|path| { + trap.emit(generated::PathTypeRepr { + id: trap::TrapId::Star, + path: Some(path), + }) + }); + if let Some(trait_ref) = trait_ref { + generated::PathSegment::emit_trait_type_repr(qualifier, trait_ref, &mut trap.writer) + } + let data = db.type_alias_data(from_assoc_type_id(*associated_ty_id)); + + let identifier = Some(trap.emit(generated::NameRef { + id: trap::TrapId::Star, + text: Some(data.name.as_str().to_owned()), + })); + let segment = trap.emit(generated::PathSegment { + id: trap::TrapId::Star, + generic_arg_list: None, + identifier, + parenthesized_arg_list: None, + ret_type: None, + return_type_syntax: None, + }); + let qualifier = trap.emit(generated::Path { + id: trap::TrapId::Star, + qualifier: None, + segment: Some(qualifier), + }); + let path = trap.emit(generated::Path { + id: trap::TrapId::Star, + qualifier: Some(qualifier), + segment: Some(segment), + }); + Some( + trap.emit(generated::PathTypeRepr { + id: trap::TrapId::Star, + path: Some(path), + }) + .into(), + ) } chalk_ir::TyKind::BoundVar(var) => { - let var = format!("T_{}_{}", var.debruijn.depth(), var.index); - let path = make_qualified_path(trap, vec![var]); + let var_ = ty_vars + .get(ty_vars.len() - 1 - var.debruijn.depth() as usize) + .and_then(|ty_vars| ty_vars.get(var.index)); + let path = make_qualified_path( + trap, + vec![ + var_.unwrap_or(&format!("E_{}_{}", var.debruijn.depth(), var.index)) + .clone(), + ], + None, + ); Some( trap.emit(generated::PathTypeRepr { id: trap::TrapId::Star, @@ -1256,6 +1411,87 @@ fn emit_hir_ty( } } +fn emit_generic_arg_list( + trap: &mut TrapFile, + db: &dyn HirDatabase, + ty_vars: &[Vec], + args: &[GenericArg], +) -> Option> { + if args.is_empty() { + return None; + } + let generic_args = args + .iter() + .flat_map(|arg| { + if let Some(ty) = arg.ty(Interner) { + let type_repr = emit_hir_ty(trap, db, ty_vars, ty); + Some( + trap.emit(generated::TypeArg { + id: trap::TrapId::Star, + type_repr, + }) + .into(), + ) + } else if let Some(l) = arg.lifetime(Interner) { + let lifetime = emit_lifetime(trap, ty_vars, l); + Some( + trap.emit(generated::LifetimeArg { + id: trap::TrapId::Star, + lifetime: Some(lifetime), + }) + .into(), + ) + } else if arg.constant(Interner).is_some() { + Some( + trap.emit(generated::ConstArg { + id: trap::TrapId::Star, + expr: None, + }) + .into(), + ) + } else { + None + } + }) + .collect(); + + trap.emit(generated::GenericArgList { + id: trap::TrapId::Star, + generic_args, + }) + .into() +} + +fn emit_lifetime( + trap: &mut TrapFile, + ty_vars: &[Vec], + l: &chalk_ir::Lifetime, +) -> trap::Label { + let text = match l.data(Interner) { + chalk_ir::LifetimeData::BoundVar(var) => { + let var_ = ty_vars + .get(ty_vars.len() - 1 - var.debruijn.depth() as usize) + .and_then(|ty_vars| ty_vars.get(var.index)); + + Some(var_.map(|v| v.to_string()).unwrap_or(format!( + "'E_{}_{}", + var.debruijn.depth(), + var.index + ))) + } + chalk_ir::LifetimeData::Static => "'static'".to_owned().into(), + chalk_ir::LifetimeData::InferenceVar(_) + | chalk_ir::LifetimeData::Placeholder(_) + | chalk_ir::LifetimeData::Erased + | chalk_ir::LifetimeData::Phantom(_, _) + | chalk_ir::LifetimeData::Error => None, + }; + trap.emit(generated::Lifetime { + id: trap::TrapId::Star, + text, + }) +} + enum Variant { Unit, Record(trap::Label), @@ -1266,7 +1502,7 @@ impl From for Option> { fn from(val: Variant) -> Self { match val { Variant::Record(label) => Some(label), - _ => None, + Variant::Unit | Variant::Tuple(_) => None, } } } @@ -1281,7 +1517,13 @@ impl From for Option> { } } -fn emit_variant_data(trap: &mut TrapFile, db: &dyn HirDatabase, variant_id: VariantId) -> Variant { +fn emit_variant_data( + trap: &mut TrapFile, + db: &dyn HirDatabase, + ty_vars: &[Vec], + variant_id: VariantId, +) -> Variant { + let parameters_len = ty_vars.last().map_or(0, Vec::len); let variant = variant_id.variant_data(db.upcast()); match variant.as_ref() { VariantData::Record { @@ -1296,7 +1538,8 @@ fn emit_variant_data(trap: &mut TrapFile, db: &dyn HirDatabase, variant_id: Vari id: trap::TrapId::Star, text: Some(field_data[field_id].name.as_str().to_owned()), })); - let type_repr = emit_hir_ty(trap, db, ty.skip_binders()); + assert_eq!(ty.binders.len(Interner), parameters_len); + let type_repr = emit_hir_ty(trap, db, ty_vars, ty.skip_binders()); let visibility = emit_visibility( db, trap, @@ -1307,7 +1550,7 @@ fn emit_variant_data(trap: &mut TrapFile, db: &dyn HirDatabase, variant_id: Vari trap.emit(generated::StructField { id: trap::TrapId::Star, attrs: vec![], - is_unsafe: false, + is_unsafe: field_data[field_id].is_unsafe, name, type_repr, visibility, @@ -1327,7 +1570,8 @@ fn emit_variant_data(trap: &mut TrapFile, db: &dyn HirDatabase, variant_id: Vari let fields = field_types .iter() .map(|(field_id, ty)| { - let type_repr = emit_hir_ty(trap, db, ty.skip_binders()); + assert_eq!(ty.binders.len(Interner), parameters_len); + let type_repr = emit_hir_ty(trap, db, ty_vars, ty.skip_binders()); let visibility = emit_visibility( db, trap, diff --git a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll index 08bc22901fe8..e15f5733748a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/LifetimeImpl.qll @@ -20,7 +20,7 @@ module Impl { */ class Lifetime extends Generated::Lifetime { override string toStringImpl() { - result = "'" + this.getText() + result = this.getText() or not this.hasText() and result = "'_" } diff --git a/rust/ql/test/extractor-tests/crate_graph/module.rs b/rust/ql/test/extractor-tests/crate_graph/module.rs index 17ef271a7292..0cb34cbcb1ba 100644 --- a/rust/ql/test/extractor-tests/crate_graph/module.rs +++ b/rust/ql/test/extractor-tests/crate_graph/module.rs @@ -43,3 +43,16 @@ pub static X_B: X = X::B; pub use std::fs::create_dir as mkdir; pub use std::{fs::*, path::PathBuf}; + +pub struct LocalKey { + inner: fn(Option<&mut Option>) -> *const T, +} + +pub struct Thing { + x: T, +} +impl From for Thing { + fn from(_x: usize) -> Self { + Thing { x: X::A } + } +} diff --git a/rust/ql/test/extractor-tests/crate_graph/modules.expected b/rust/ql/test/extractor-tests/crate_graph/modules.expected index 40ee24579e07..157432a77e33 100644 --- a/rust/ql/test/extractor-tests/crate_graph/modules.expected +++ b/rust/ql/test/extractor-tests/crate_graph/modules.expected @@ -10,13 +10,18 @@ #-----| fn fmt +#-----| fn from + #-----| fn length +#-----| impl ...::AsString for ...::X { ... } +#-----| -> fn as_string + #-----| impl ...::Display for ...::X { ... } #-----| -> fn fmt -#-----| impl AsString for ...::X { ... } -#-----| -> fn as_string +#-----| impl ...::From::<...> for ...::Thing::<...> { ... } +#-----| -> fn from lib.rs: # 0| mod crate @@ -27,8 +32,11 @@ lib.rs: #-----| -> Static #-----| -> enum X #-----| -> fn length +#-----| -> impl ...::AsString for ...::X { ... } #-----| -> impl ...::Display for ...::X { ... } -#-----| -> impl AsString for ...::X { ... } +#-----| -> impl ...::From::<...> for ...::Thing::<...> { ... } +#-----| -> struct LocalKey +#-----| -> struct Thing #-----| -> struct X_List #-----| -> trait AsString #-----| -> use ...::DirBuilder @@ -62,6 +70,10 @@ lib.rs: #-----| -> use ...::symlink_metadata #-----| -> use ...::write +#-----| struct LocalKey + +#-----| struct Thing + #-----| struct X_List #-----| trait AsString diff --git a/rust/ql/test/extractor-tests/crate_graph/modules.ql b/rust/ql/test/extractor-tests/crate_graph/modules.ql index 42b0e5c0fcbb..5554a69d1a96 100644 --- a/rust/ql/test/extractor-tests/crate_graph/modules.ql +++ b/rust/ql/test/extractor-tests/crate_graph/modules.ql @@ -13,6 +13,33 @@ class RelevantNode extends Item { this.getParentNode*() = any(Crate m | m.getName() = "test" and m.getVersion() = "0.0.1").getModule() } + + string label() { result = this.toString() } +} + +class HasGenericParams extends RelevantNode { + private GenericParamList params; + + HasGenericParams() { + params = this.(Function).getGenericParamList() or + params = this.(Enum).getGenericParamList() or + params = this.(Struct).getGenericParamList() or + params = this.(Union).getGenericParamList() or + params = this.(Impl).getGenericParamList() or + params = this.(Enum).getGenericParamList() or + params = this.(Trait).getGenericParamList() or + params = this.(TraitAlias).getGenericParamList() + } + + override string label() { + result = + super.toString() + "<" + + strictconcat(string part, int index | + part = params.getGenericParam(index).toString() + | + part, ", " order by index + ) + ">" + } } predicate edges(RelevantNode container, RelevantNode element) { @@ -25,7 +52,7 @@ query predicate nodes(RelevantNode node, string attr, string val) { nodes(node) and ( attr = "semmle.label" and - val = node.toString() + val = node.label() or attr = "semmle.order" and val = diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected index 30c734fd682d..26a3ea2d9987 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr.expected @@ -1,3 +1,3 @@ | gen_break_expr.rs:7:13:7:17 | break | getNumberOfAttrs: | 0 | hasExpr: | no | hasLifetime: | no | -| gen_break_expr.rs:12:13:12:27 | break ''label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | -| gen_break_expr.rs:17:13:17:27 | break ''label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:12:13:12:27 | break 'label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | +| gen_break_expr.rs:17:13:17:27 | break 'label 42 | getNumberOfAttrs: | 0 | hasExpr: | yes | hasLifetime: | yes | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected index 20c5295354af..276f1d3333be 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | break ''label 42 | gen_break_expr.rs:12:26:12:27 | 42 | -| gen_break_expr.rs:17:13:17:27 | break ''label 42 | gen_break_expr.rs:17:26:17:27 | 42 | +| gen_break_expr.rs:12:13:12:27 | break 'label 42 | gen_break_expr.rs:12:26:12:27 | 42 | +| gen_break_expr.rs:17:13:17:27 | break 'label 42 | gen_break_expr.rs:17:26:17:27 | 42 | diff --git a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected index 2e1a88017950..09f1132362f6 100644 --- a/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.expected @@ -1,2 +1,2 @@ -| gen_break_expr.rs:12:13:12:27 | break ''label 42 | gen_break_expr.rs:12:19:12:24 | ''label | -| gen_break_expr.rs:17:13:17:27 | break ''label 42 | gen_break_expr.rs:17:19:17:24 | ''label | +| gen_break_expr.rs:12:13:12:27 | break 'label 42 | gen_break_expr.rs:12:19:12:24 | 'label | +| gen_break_expr.rs:17:13:17:27 | break 'label 42 | gen_break_expr.rs:17:19:17:24 | 'label | diff --git a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected index d81d276ce0ae..3260e45d1b74 100644 --- a/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.expected @@ -1 +1 @@ -| gen_continue_expr.rs:12:13:12:27 | continue 'label | gen_continue_expr.rs:12:22:12:27 | ''label | +| gen_continue_expr.rs:12:13:12:27 | continue 'label | gen_continue_expr.rs:12:22:12:27 | 'label | diff --git a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected index 73ebbe963e85..9bbe91519133 100644 --- a/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/Label/Label_getLifetime.expected @@ -1 +1 @@ -| gen_label.rs:5:5:5:11 | 'label | gen_label.rs:5:5:5:10 | ''label | +| gen_label.rs:5:5:5:11 | 'label | gen_label.rs:5:5:5:10 | 'label | diff --git a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getLifetime.expected b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getLifetime.expected index 47e9eba10acc..cfe91c68c858 100644 --- a/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getLifetime.expected +++ b/rust/ql/test/extractor-tests/generated/SelfParam/SelfParam_getLifetime.expected @@ -1 +1 @@ -| gen_self_param.rs:10:15:10:22 | SelfParam | gen_self_param.rs:10:16:10:17 | ''a | +| gen_self_param.rs:10:15:10:22 | SelfParam | gen_self_param.rs:10:16:10:17 | 'a | diff --git a/rust/ql/test/extractor-tests/utf8/ast.expected b/rust/ql/test/extractor-tests/utf8/ast.expected index 58f926364c04..a37eed8e2641 100644 --- a/rust/ql/test/extractor-tests/utf8/ast.expected +++ b/rust/ql/test/extractor-tests/utf8/ast.expected @@ -5,7 +5,7 @@ | utf8_identifiers.rs:1:1:12:2 | SourceFile | | utf8_identifiers.rs:1:4:1:6 | foo | | utf8_identifiers.rs:1:7:4:1 | <...> | -| utf8_identifiers.rs:2:5:2:6 | ''\u03b2 | +| utf8_identifiers.rs:2:5:2:6 | '\u03b2 | | utf8_identifiers.rs:2:5:2:6 | LifetimeParam | | utf8_identifiers.rs:3:5:3:5 | \u03b3 | | utf8_identifiers.rs:3:5:3:5 | \u03b3 | diff --git a/rust/ql/test/library-tests/controlflow/BasicBlocks.expected b/rust/ql/test/library-tests/controlflow/BasicBlocks.expected index 8de7e7066cd8..d5d978b9f52a 100644 --- a/rust/ql/test/library-tests/controlflow/BasicBlocks.expected +++ b/rust/ql/test/library-tests/controlflow/BasicBlocks.expected @@ -304,8 +304,8 @@ dominates | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:227:9:236:9 | if ... {...} else {...} | | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:228:13:230:13 | if ... {...} | | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:228:13:230:14 | ExprStmt | -| test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:229:17:229:36 | ExprStmt | | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:233:13:233:13 | 1 | | test.rs:226:5:237:5 | enter fn test_if_loop2 | test.rs:235:13:235:13 | 0 | @@ -314,18 +314,18 @@ dominates | test.rs:228:13:230:14 | ExprStmt | test.rs:227:9:236:9 | if ... {...} else {...} | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:13 | if ... {...} | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:14 | ExprStmt | -| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:36 | ExprStmt | | test.rs:228:13:230:14 | ExprStmt | test.rs:233:13:233:13 | 1 | | test.rs:228:13:230:14 | ExprStmt | test.rs:235:13:235:13 | 0 | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:235:13:235:13 | 0 | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:233:13:233:13 | 1 | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:235:13:235:13 | 0 | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:233:13:233:13 | 1 | | test.rs:229:17:229:36 | ExprStmt | test.rs:227:9:236:9 | if ... {...} else {...} | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:36 | ExprStmt | | test.rs:229:17:229:36 | ExprStmt | test.rs:233:13:233:13 | 1 | | test.rs:229:17:229:36 | ExprStmt | test.rs:235:13:235:13 | 0 | @@ -333,15 +333,15 @@ dominates | test.rs:235:13:235:13 | 0 | test.rs:235:13:235:13 | 0 | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:239:5:247:5 | enter fn test_labelled_block | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:240:9:246:9 | if ... {...} else {...} | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:243:13:243:13 | 1 | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:245:13:245:13 | 0 | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:240:9:246:9 | if ... {...} else {...} | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:245:13:245:13 | 0 | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:243:13:243:13 | 1 | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:245:13:245:13 | 0 | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:243:13:243:13 | 1 | | test.rs:243:13:243:13 | 1 | test.rs:243:13:243:13 | 1 | | test.rs:245:13:245:13 | 0 | test.rs:245:13:245:13 | 0 | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:252:5:255:5 | enter fn test_and_operator | @@ -1031,8 +1031,8 @@ postDominance | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:227:9:236:9 | if ... {...} else {...} | | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:228:13:230:13 | if ... {...} | | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:228:13:230:14 | ExprStmt | -| test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:36 | ExprStmt | | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:233:13:233:13 | 1 | | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:235:13:235:13 | 0 | @@ -1040,28 +1040,28 @@ postDominance | test.rs:228:13:230:14 | ExprStmt | test.rs:226:5:237:5 | enter fn test_if_loop2 | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:13 | if ... {...} | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:14 | ExprStmt | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:229:17:229:36 | ExprStmt | test.rs:226:5:237:5 | enter fn test_if_loop2 | | test.rs:229:17:229:36 | ExprStmt | test.rs:228:13:230:13 | if ... {...} | | test.rs:229:17:229:36 | ExprStmt | test.rs:228:13:230:14 | ExprStmt | | test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:36 | ExprStmt | -| test.rs:233:13:233:13 | 1 | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | +| test.rs:233:13:233:13 | 1 | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | | test.rs:233:13:233:13 | 1 | test.rs:233:13:233:13 | 1 | -| test.rs:235:13:235:13 | 0 | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | +| test.rs:235:13:235:13 | 0 | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | | test.rs:235:13:235:13 | 0 | test.rs:235:13:235:13 | 0 | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:239:5:247:5 | enter fn test_labelled_block | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:239:5:247:5 | enter fn test_labelled_block | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:240:9:246:9 | if ... {...} else {...} | -| test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | -| test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | +| test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | +| test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:243:13:243:13 | 1 | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:245:13:245:13 | 0 | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | -| test.rs:243:13:243:13 | 1 | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | +| test.rs:243:13:243:13 | 1 | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | | test.rs:243:13:243:13 | 1 | test.rs:243:13:243:13 | 1 | -| test.rs:245:13:245:13 | 0 | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | +| test.rs:245:13:245:13 | 0 | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | | test.rs:245:13:245:13 | 0 | test.rs:245:13:245:13 | 0 | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:252:5:255:5 | enter fn test_and_operator | | test.rs:253:17:253:22 | [boolean(false)] ... && ... | test.rs:253:17:253:22 | [boolean(false)] ... && ... | @@ -1543,16 +1543,16 @@ immediateDominator | test.rs:227:9:236:9 | if ... {...} else {...} | test.rs:229:17:229:36 | ExprStmt | | test.rs:228:13:230:13 | if ... {...} | test.rs:228:13:230:14 | ExprStmt | | test.rs:228:13:230:14 | ExprStmt | test.rs:226:5:237:5 | enter fn test_if_loop2 | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:229:17:229:36 | ExprStmt | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:229:17:229:36 | ExprStmt | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:229:17:229:36 | ExprStmt | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:229:17:229:36 | ExprStmt | | test.rs:229:17:229:36 | ExprStmt | test.rs:228:13:230:14 | ExprStmt | -| test.rs:233:13:233:13 | 1 | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | -| test.rs:235:13:235:13 | 0 | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | +| test.rs:233:13:233:13 | 1 | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | +| test.rs:235:13:235:13 | 0 | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:239:5:247:5 | enter fn test_labelled_block | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:239:5:247:5 | enter fn test_labelled_block | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:239:5:247:5 | enter fn test_labelled_block | -| test.rs:243:13:243:13 | 1 | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | -| test.rs:245:13:245:13 | 0 | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:239:5:247:5 | enter fn test_labelled_block | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:239:5:247:5 | enter fn test_labelled_block | +| test.rs:243:13:243:13 | 1 | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | +| test.rs:245:13:245:13 | 0 | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | | test.rs:253:17:253:22 | [boolean(false)] ... && ... | test.rs:252:5:255:5 | enter fn test_and_operator | | test.rs:253:17:253:22 | [boolean(true)] ... && ... | test.rs:253:22:253:22 | b | | test.rs:253:17:253:27 | ... && ... | test.rs:252:5:255:5 | enter fn test_and_operator | @@ -1798,23 +1798,23 @@ controls | test.rs:216:17:216:29 | ExprStmt | test.rs:222:13:222:13 | 0 | false | | test.rs:228:13:230:14 | ExprStmt | test.rs:227:9:236:9 | if ... {...} else {...} | true | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:13 | if ... {...} | false | -| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | true | -| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | true | +| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | true | +| test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | true | | test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:36 | ExprStmt | true | | test.rs:228:13:230:14 | ExprStmt | test.rs:233:13:233:13 | 1 | true | | test.rs:228:13:230:14 | ExprStmt | test.rs:235:13:235:13 | 0 | true | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:235:13:235:13 | 0 | false | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:233:13:233:13 | 1 | true | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | false | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | true | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:235:13:235:13 | 0 | false | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:233:13:233:13 | 1 | true | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | false | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | true | | test.rs:229:17:229:36 | ExprStmt | test.rs:233:13:233:13 | 1 | true | | test.rs:229:17:229:36 | ExprStmt | test.rs:235:13:235:13 | 0 | false | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | false | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | true | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | false | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | true | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:243:13:243:13 | 1 | true | | test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:245:13:245:13 | 0 | false | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:245:13:245:13 | 0 | false | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:243:13:243:13 | 1 | true | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:245:13:245:13 | 0 | false | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:243:13:243:13 | 1 | true | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:253:17:253:22 | [boolean(true)] ... && ... | true | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:253:22:253:22 | b | true | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:253:27:253:27 | c | true | @@ -1974,14 +1974,14 @@ successor | test.rs:216:17:216:29 | ExprStmt | test.rs:216:17:216:28 | [boolean(true)] break ... | true | | test.rs:228:13:230:14 | ExprStmt | test.rs:228:13:230:13 | if ... {...} | false | | test.rs:228:13:230:14 | ExprStmt | test.rs:229:17:229:36 | ExprStmt | true | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:235:13:235:13 | 0 | false | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:233:13:233:13 | 1 | true | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | false | -| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | true | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | false | -| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | true | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:245:13:245:13 | 0 | false | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:243:13:243:13 | 1 | true | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:235:13:235:13 | 0 | false | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:233:13:233:13 | 1 | true | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | false | +| test.rs:229:17:229:36 | ExprStmt | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | true | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | false | +| test.rs:239:5:247:5 | enter fn test_labelled_block | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | true | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:245:13:245:13 | 0 | false | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:243:13:243:13 | 1 | true | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:253:17:253:22 | [boolean(false)] ... && ... | false | | test.rs:252:5:255:5 | enter fn test_and_operator | test.rs:253:22:253:22 | b | true | | test.rs:253:17:253:22 | [boolean(false)] ... && ... | test.rs:253:17:253:27 | ... && ... | false | diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 40348a474e5f..1705b88e3d75 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -119,10 +119,10 @@ edges | test.rs:49:24:51:17 | if b {...} | test.rs:47:17:51:17 | if b {...} else {...} | | | test.rs:49:27:49:27 | b | test.rs:49:24:51:17 | if b {...} | false | | test.rs:49:27:49:27 | b | test.rs:50:21:50:33 | ExprStmt | true | -| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | 'outer: loop { ... } | break | -| test.rs:50:21:50:33 | ExprStmt | test.rs:50:21:50:32 | break ''outer | | -| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | 'inner: loop { ... } | break | -| test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | break ''inner | | +| test.rs:50:21:50:32 | break 'outer | test.rs:45:9:54:9 | 'outer: loop { ... } | break | +| test.rs:50:21:50:33 | ExprStmt | test.rs:50:21:50:32 | break 'outer | | +| test.rs:52:17:52:28 | break 'inner | test.rs:46:13:53:13 | 'inner: loop { ... } | break | +| test.rs:52:17:52:29 | ExprStmt | test.rs:52:17:52:28 | break 'inner | | | test.rs:55:9:55:12 | true | test.rs:44:48:56:5 | { ... } | | | test.rs:58:5:70:5 | enter fn test_continue_with_labels | test.rs:58:34:58:34 | b | | | test.rs:58:34:58:34 | b | test.rs:58:34:58:34 | b | | @@ -534,12 +534,12 @@ edges | test.rs:228:16:228:20 | ... > ... | test.rs:228:13:230:13 | if ... {...} | false | | test.rs:228:16:228:20 | ... > ... | test.rs:229:17:229:36 | ExprStmt | true | | test.rs:228:20:228:20 | 0 | test.rs:228:16:228:20 | ... > ... | | -| test.rs:229:17:229:35 | [boolean(false)] break ''label ... | test.rs:227:13:232:9 | [boolean(false)] 'label: loop { ... } | break | -| test.rs:229:17:229:35 | [boolean(true)] break ''label ... | test.rs:227:13:232:9 | [boolean(true)] 'label: loop { ... } | break | +| test.rs:229:17:229:35 | [boolean(false)] break 'label ... | test.rs:227:13:232:9 | [boolean(false)] 'label: loop { ... } | break | +| test.rs:229:17:229:35 | [boolean(true)] break 'label ... | test.rs:227:13:232:9 | [boolean(true)] 'label: loop { ... } | break | | test.rs:229:17:229:36 | ExprStmt | test.rs:229:30:229:30 | a | | | test.rs:229:30:229:30 | a | test.rs:229:34:229:35 | 10 | | -| test.rs:229:30:229:35 | ... > ... | test.rs:229:17:229:35 | [boolean(false)] break ''label ... | false | -| test.rs:229:30:229:35 | ... > ... | test.rs:229:17:229:35 | [boolean(true)] break ''label ... | true | +| test.rs:229:30:229:35 | ... > ... | test.rs:229:17:229:35 | [boolean(false)] break 'label ... | false | +| test.rs:229:30:229:35 | ... > ... | test.rs:229:17:229:35 | [boolean(true)] break 'label ... | true | | test.rs:229:34:229:35 | 10 | test.rs:229:30:229:35 | ... > ... | | | test.rs:231:13:231:13 | a | test.rs:231:17:231:18 | 10 | | | test.rs:231:13:231:18 | ... < ... | test.rs:227:26:232:9 | { ... } | | @@ -558,12 +558,12 @@ edges | test.rs:240:9:246:9 | if ... {...} else {...} | test.rs:239:43:247:5 | { ... } | | | test.rs:240:13:242:9 | [boolean(false)] 'block: { ... } | test.rs:245:13:245:13 | 0 | false | | test.rs:240:13:242:9 | [boolean(true)] 'block: { ... } | test.rs:243:13:243:13 | 1 | true | -| test.rs:241:13:241:30 | [boolean(false)] break ''block ... | test.rs:240:13:242:9 | [boolean(false)] 'block: { ... } | break | -| test.rs:241:13:241:30 | [boolean(true)] break ''block ... | test.rs:240:13:242:9 | [boolean(true)] 'block: { ... } | break | +| test.rs:241:13:241:30 | [boolean(false)] break 'block ... | test.rs:240:13:242:9 | [boolean(false)] 'block: { ... } | break | +| test.rs:241:13:241:30 | [boolean(true)] break 'block ... | test.rs:240:13:242:9 | [boolean(true)] 'block: { ... } | break | | test.rs:241:13:241:31 | ExprStmt | test.rs:241:26:241:26 | a | | | test.rs:241:26:241:26 | a | test.rs:241:30:241:30 | 0 | | -| test.rs:241:26:241:30 | ... > ... | test.rs:241:13:241:30 | [boolean(false)] break ''block ... | false | -| test.rs:241:26:241:30 | ... > ... | test.rs:241:13:241:30 | [boolean(true)] break ''block ... | true | +| test.rs:241:26:241:30 | ... > ... | test.rs:241:13:241:30 | [boolean(false)] break 'block ... | false | +| test.rs:241:26:241:30 | ... > ... | test.rs:241:13:241:30 | [boolean(true)] break 'block ... | true | | test.rs:241:30:241:30 | 0 | test.rs:241:26:241:30 | ... > ... | | | test.rs:242:12:244:9 | { ... } | test.rs:240:9:246:9 | if ... {...} else {...} | | | test.rs:243:13:243:13 | 1 | test.rs:242:12:244:9 | { ... } | | @@ -1364,9 +1364,9 @@ edges | test.rs:571:12:571:28 | condition_not_met | test.rs:571:12:571:30 | condition_not_met(...) | | | test.rs:571:12:571:30 | condition_not_met(...) | test.rs:571:9:573:9 | if ... {...} | false | | test.rs:571:12:571:30 | condition_not_met(...) | test.rs:572:13:572:27 | ExprStmt | true | -| test.rs:572:13:572:26 | break ''block 1 | test.rs:569:18:580:5 | 'block: { ... } | break | +| test.rs:572:13:572:26 | break 'block 1 | test.rs:569:18:580:5 | 'block: { ... } | break | | test.rs:572:13:572:27 | ExprStmt | test.rs:572:26:572:26 | 1 | | -| test.rs:572:26:572:26 | 1 | test.rs:572:13:572:26 | break ''block 1 | | +| test.rs:572:26:572:26 | 1 | test.rs:572:13:572:26 | break 'block 1 | | | test.rs:574:9:574:21 | do_next_thing | test.rs:574:9:574:23 | do_next_thing(...) | | | test.rs:574:9:574:23 | do_next_thing(...) | test.rs:575:9:577:9 | ExprStmt | | | test.rs:574:9:574:24 | ExprStmt | test.rs:574:9:574:21 | do_next_thing | | @@ -1375,9 +1375,9 @@ edges | test.rs:575:12:575:28 | condition_not_met | test.rs:575:12:575:30 | condition_not_met(...) | | | test.rs:575:12:575:30 | condition_not_met(...) | test.rs:575:9:577:9 | if ... {...} | false | | test.rs:575:12:575:30 | condition_not_met(...) | test.rs:576:13:576:27 | ExprStmt | true | -| test.rs:576:13:576:26 | break ''block 2 | test.rs:569:18:580:5 | 'block: { ... } | break | +| test.rs:576:13:576:26 | break 'block 2 | test.rs:569:18:580:5 | 'block: { ... } | break | | test.rs:576:13:576:27 | ExprStmt | test.rs:576:26:576:26 | 2 | | -| test.rs:576:26:576:26 | 2 | test.rs:576:13:576:26 | break ''block 2 | | +| test.rs:576:26:576:26 | 2 | test.rs:576:13:576:26 | break 'block 2 | | | test.rs:578:9:578:21 | do_last_thing | test.rs:578:9:578:23 | do_last_thing(...) | | | test.rs:578:9:578:23 | do_last_thing(...) | test.rs:579:9:579:9 | 3 | | | test.rs:578:9:578:24 | ExprStmt | test.rs:578:9:578:21 | do_last_thing | | @@ -1400,9 +1400,9 @@ edges | test.rs:587:18:587:18 | y | test.rs:587:18:587:18 | y | | | test.rs:587:18:587:18 | y | test.rs:590:9:590:9 | 0 | match | | test.rs:587:23:587:23 | x | test.rs:587:13:587:19 | Some(...) | | -| test.rs:588:13:588:26 | break ''block 1 | test.rs:585:18:591:5 | 'block: { ... } | break | +| test.rs:588:13:588:26 | break 'block 1 | test.rs:585:18:591:5 | 'block: { ... } | break | | test.rs:588:13:588:27 | ExprStmt | test.rs:588:26:588:26 | 1 | | -| test.rs:588:26:588:26 | 1 | test.rs:588:13:588:26 | break ''block 1 | | +| test.rs:588:26:588:26 | 1 | test.rs:588:13:588:26 | break 'block 1 | | | test.rs:590:9:590:9 | 0 | test.rs:585:18:591:5 | 'block: { ... } | | | test.rs:594:1:600:1 | enter fn test_nested_function2 | test.rs:595:5:595:18 | let ... = 0 | | | test.rs:594:1:600:1 | exit fn test_nested_function2 (normal) | test.rs:594:1:600:1 | exit fn test_nested_function2 | | @@ -1468,18 +1468,18 @@ edges breakTarget | test.rs:34:17:34:21 | break | test.rs:28:9:40:9 | loop { ... } | | test.rs:48:21:48:25 | break | test.rs:46:13:53:13 | 'inner: loop { ... } | -| test.rs:50:21:50:32 | break ''outer | test.rs:45:9:54:9 | 'outer: loop { ... } | -| test.rs:52:17:52:28 | break ''inner | test.rs:46:13:53:13 | 'inner: loop { ... } | +| test.rs:50:21:50:32 | break 'outer | test.rs:45:9:54:9 | 'outer: loop { ... } | +| test.rs:52:17:52:28 | break 'inner | test.rs:46:13:53:13 | 'inner: loop { ... } | | test.rs:91:17:91:21 | break | test.rs:88:9:94:9 | while b { ... } | | test.rs:101:17:101:21 | break | test.rs:99:9:103:9 | while ... { ... } | | test.rs:109:17:109:21 | break | test.rs:107:9:112:9 | for ... in ... { ... } | | test.rs:117:13:117:26 | break ... | test.rs:116:9:118:9 | loop { ... } | | test.rs:216:17:216:28 | break ... | test.rs:214:13:219:9 | loop { ... } | -| test.rs:229:17:229:35 | break ''label ... | test.rs:227:13:232:9 | 'label: loop { ... } | -| test.rs:241:13:241:30 | break ''block ... | test.rs:240:13:242:9 | 'block: { ... } | -| test.rs:572:13:572:26 | break ''block 1 | test.rs:569:18:580:5 | 'block: { ... } | -| test.rs:576:13:576:26 | break ''block 2 | test.rs:569:18:580:5 | 'block: { ... } | -| test.rs:588:13:588:26 | break ''block 1 | test.rs:585:18:591:5 | 'block: { ... } | +| test.rs:229:17:229:35 | break 'label ... | test.rs:227:13:232:9 | 'label: loop { ... } | +| test.rs:241:13:241:30 | break 'block ... | test.rs:240:13:242:9 | 'block: { ... } | +| test.rs:572:13:572:26 | break 'block 1 | test.rs:569:18:580:5 | 'block: { ... } | +| test.rs:576:13:576:26 | break 'block 2 | test.rs:569:18:580:5 | 'block: { ... } | +| test.rs:588:13:588:26 | break 'block 1 | test.rs:585:18:591:5 | 'block: { ... } | continueTarget | test.rs:37:17:37:24 | continue | test.rs:28:9:40:9 | loop { ... } | | test.rs:63:21:63:28 | continue | test.rs:61:13:68:13 | 'inner: loop { ... } | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index c147ec62e2e9..79b0ebc62f04 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -90,8 +90,8 @@ localStep | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a | | main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | a | | main.rs:66:13:71:5 | 'block: { ... } | main.rs:66:9:66:9 | a | -| main.rs:68:13:68:26 | break ''block 1 | main.rs:66:13:71:5 | 'block: { ... } | -| main.rs:68:26:68:26 | 1 | main.rs:68:13:68:26 | break ''block 1 | +| main.rs:68:13:68:26 | break 'block 1 | main.rs:66:13:71:5 | 'block: { ... } | +| main.rs:68:26:68:26 | 1 | main.rs:68:13:68:26 | break 'block 1 | | main.rs:70:9:70:9 | 2 | main.rs:66:13:71:5 | 'block: { ... } | | main.rs:72:5:72:5 | a | main.rs:65:38:73:1 | { ... } | | main.rs:75:22:75:22 | [SSA] b | main.rs:77:12:77:12 | b | @@ -102,10 +102,10 @@ localStep | main.rs:76:9:76:9 | a | main.rs:76:9:76:9 | [SSA] a | | main.rs:76:9:76:9 | a | main.rs:76:9:76:9 | a | | main.rs:76:13:81:5 | 'block: { ... } | main.rs:76:9:76:9 | a | -| main.rs:78:13:78:26 | break ''block 1 | main.rs:76:13:81:5 | 'block: { ... } | -| main.rs:78:26:78:26 | 1 | main.rs:78:13:78:26 | break ''block 1 | -| main.rs:80:9:80:22 | break ''block 2 | main.rs:76:13:81:5 | 'block: { ... } | -| main.rs:80:22:80:22 | 2 | main.rs:80:9:80:22 | break ''block 2 | +| main.rs:78:13:78:26 | break 'block 1 | main.rs:76:13:81:5 | 'block: { ... } | +| main.rs:78:26:78:26 | 1 | main.rs:78:13:78:26 | break 'block 1 | +| main.rs:80:9:80:22 | break 'block 2 | main.rs:76:13:81:5 | 'block: { ... } | +| main.rs:80:22:80:22 | 2 | main.rs:80:9:80:22 | break 'block 2 | | main.rs:82:5:82:5 | a | main.rs:75:38:83:1 | { ... } | | main.rs:89:9:89:9 | [SSA] i | main.rs:90:11:90:11 | i | | main.rs:89:9:89:9 | i | main.rs:89:9:89:9 | [SSA] i |