Skip to content

Commit

Permalink
Cleanup visit_function_reference calls
Browse files Browse the repository at this point in the history
  • Loading branch information
hermanventer committed Dec 5, 2024
1 parent 2f07820 commit d938fcb
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 42 deletions.
Binary file modified binaries/summary_store.tar
Binary file not shown.
57 changes: 26 additions & 31 deletions checker/src/block_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
&actual_argument_types,
);
let fun_ty = tcx.type_of(destructor.did).skip_binder();
// todo: perhaps use the type of the struct (ty) instead of fun_ty
// since ty is specialized, fun_ty and args should be specialized as well.
let func_const = self
.visit_function_reference(destructor.did, fun_ty, Some(args))
.clone();
Expand Down Expand Up @@ -1047,9 +1047,11 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
if let TyKind::Closure(def_id, args) | TyKind::FnDef(def_id, args) =
specialized_closure_ty.kind()
{
let fun_ty = self.bv.tcx.type_of(def_id).skip_binder();
// since specialized_closure_ty is specialized, fun_ty and args should be specialized as well.
return extract_func_ref(self.visit_function_reference(
*def_id,
specialized_closure_ty,
fun_ty,
Some(args),
));
}
Expand Down Expand Up @@ -2661,12 +2663,15 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
mir::AggregateKind::Closure(def_id, args)
| mir::AggregateKind::Coroutine(def_id, args)
| mir::AggregateKind::CoroutineClosure(def_id, args) => {
// todo: perhaps this should be
// let ty = self
// .type_visitor()
// .get_path_rustc_type(&path, self.bv.current_span);
let ty = self.bv.tcx.type_of(*def_id).skip_binder();
let func_const = self.visit_function_reference(*def_id, ty, Some(args));
let specialized_ty = self
.type_visitor()
.specialize_type(ty, &self.type_visitor().generic_argument_map);
let specialized_args = self
.type_visitor()
.specialize_generic_args(args, &self.type_visitor().generic_argument_map);
let func_const =
self.visit_function_reference(*def_id, specialized_ty, Some(specialized_args));
let func_val = Rc::new(func_const.clone().into());
self.bv.update_value_at(path.clone(), func_val);
for (i, operand) in operands.iter().enumerate() {
Expand Down Expand Up @@ -3601,22 +3606,18 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
bytes_left_deserialize
}
// todo: bytes is the serialization of the captured state of a closure/generator
// deserialize that and return an heap block that represents the closure state + func ptr
// deserialize that and return a heap block that represents the closure state + func ptr
TyKind::Closure(def_id, args)
| TyKind::FnDef(def_id, args)
| TyKind::Coroutine(def_id, args, ..)
| TyKind::Alias(
rustc_middle::ty::Opaque,
rustc_middle::ty::AliasTy { def_id, args, .. },
) => {
let specialized_ty = self
.type_visitor()
.specialize_type(ty, &self.type_visitor().generic_argument_map);
let specialized_args = self
.type_visitor()
.specialize_generic_args(args, &self.type_visitor().generic_argument_map);
let fun_ty = self.bv.tcx.type_of(def_id).skip_binder();
// since ty is specialized, fun_ty and args should be specialized as well.
let func_val = Rc::new(
self.visit_function_reference(*def_id, specialized_ty, Some(specialized_args))
self.visit_function_reference(*def_id, fun_ty, Some(args))
.clone()
.into(),
);
Expand Down Expand Up @@ -3931,7 +3932,8 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
}
TyKind::FnDef(def_id, args) => {
debug_assert!(size == 0 && data == 0);
// todo: this seems the right approach. Make other calls sites conform.
// guard against the possibility that ty is not specialized with respect the actual
// type arguments of the current function.
let specialized_ty = self
.type_visitor()
.specialize_type(ty, &self.type_visitor().generic_argument_map);
Expand Down Expand Up @@ -4109,29 +4111,22 @@ impl<'block, 'analysis, 'compilation, 'tcx> BlockVisitor<'block, 'analysis, 'com
rustc_middle::ty::Opaque,
rustc_middle::ty::AliasTy { def_id, .. },
) => {
let ty = self.bv.tcx.type_of(*def_id).skip_binder();
let specialized_ty = self
.type_visitor()
.specialize_type(ty, &self.type_visitor().generic_argument_map);
let aliased_ty = self.bv.tcx.type_of(*def_id).skip_binder();
// since ty is specialized, aliased_ty should be specialized as well.
if let TyKind::Closure(def_id, generic_args)
| TyKind::Coroutine(def_id, generic_args) = specialized_ty.kind()
| TyKind::Coroutine(def_id, generic_args) = aliased_ty.kind()
{
let func_const = self.visit_function_reference(
*def_id,
specialized_ty,
Some(generic_args),
);
let fun_ty = self.bv.tcx.type_of(*def_id).skip_binder();
// since aliased_ty is specialized, fun_ty and generic_args should be specialized as well.
let func_const =
self.visit_function_reference(*def_id, fun_ty, Some(generic_args));
let func_val = Rc::new(func_const.clone().into());
self.bv
.update_value_at(Path::new_function(base_path.clone()), func_val);
}
}
TyKind::FnDef(def_id, generic_args) => {
let func_const = self.visit_function_reference(
*def_id,
ty,
Some(generic_args.as_closure().args),
);
let func_const = self.visit_function_reference(*def_id, ty, Some(generic_args));
let func_val = Rc::new(func_const.clone().into());
self.bv
.update_value_at(Path::new_function(base_path.clone()), func_val);
Expand Down
13 changes: 13 additions & 0 deletions checker/src/constant_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1596,14 +1596,27 @@ impl<'tcx> ConstantValueCache<'tcx> {
/// corresponds to the function identified by that DefId.
pub fn get_function_constant_for(
&mut self,
/// The identifier of the function definition.
def_id: DefId,
/// The type of the function instance
ty: Ty<'tcx>,
/// The generic arguments used to obtain the function instance
generic_args: Option<GenericArgsRef<'tcx>>,
/// The rustc type context that knows about def_id
tcx: TyCtxt<'tcx>,
/// A cache of known names to updated with this function if its name is known.
known_names_cache: &mut KnownNamesCache,
/// A cache of function summaries. It is not provided with a summary for def_id
/// at this point, but it does provide a place to cache the key string that is used
/// to cache the summary when it is created. We do this so that we can use DefIds
/// for lookups while also making the summary cache persistable.
summary_cache: &mut PersistentSummaryCache<'tcx>,
) -> &ConstantDomain {
let function_id = self.function_cache.len();
// Distinct instances of def_id will have distinct ty values, but
// since ty is anonymous we combine it with the def_id to get a unique key.
// The combination is aliased function_id to provide a more efficient key for
// other caches.
self.function_cache.entry((def_id, ty)).or_insert_with(|| {
ConstantDomain::for_function(
function_id,
Expand Down
7 changes: 5 additions & 2 deletions checker/src/summaries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,10 +388,13 @@ impl Hash for CallSiteKey<'_> {
/// Summary. The latter is cleared after every outer fixed point loop iteration.
/// Also tracks which definitions depend on (use) any particular Summary.
pub struct PersistentSummaryCache<'tcx> {
// The sled database that stores the summaries. Can be persisted between runs.
/// The sled database that stores the summaries. Can be persisted between runs.
db: Db,
// Functions that are not generic are uniquely identified by their def_id and are cached here.
/// Functions that are not generic instances are uniquely identified by their def_id and their
/// summaries are cached here.
def_id_cache: HashMap<DefId, Summary>,
/// Functions that are generic instances are identified by their function_id and their summaries
/// are cached here.
typed_cache: HashMap<usize, Summary>,
typed_cache_table: HashMap<CallSiteKey<'tcx>, HashMap<usize, Summary>>,
reference_cache: HashMap<Rc<FunctionReference>, Summary>,
Expand Down
18 changes: 9 additions & 9 deletions checker/src/type_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,12 +1055,12 @@ impl<'tcx> TypeVisitor<'tcx> {
#[logfn_inputs(TRACE)]
pub fn specialize_type(
&self,
gen_arg_type: Ty<'tcx>,
ty: Ty<'tcx>,
map: &Option<HashMap<rustc_span::Symbol, GenericArg<'tcx>>>,
) -> Ty<'tcx> {
// The projection of an associated type. For example,
// `<T as Trait<..>>::N`.
if let TyKind::Alias(rustc_middle::ty::Projection, projection) = gen_arg_type.kind() {
if let TyKind::Alias(rustc_middle::ty::Projection, projection) = ty.kind() {
let specialized_substs = self.specialize_generic_args(projection.args, map);
let item_def_id = projection.def_id;
return if utils::are_concrete(specialized_substs) {
Expand All @@ -1080,7 +1080,7 @@ impl<'tcx> TypeVisitor<'tcx> {
let item_type = self.tcx.type_of(instance_item_def_id).skip_binder();
let map =
self.get_generic_arguments_map(instance_item_def_id, instance.args, &[]);
if item_type == gen_arg_type && map.is_none() {
if item_type == ty && map.is_none() {
// Can happen if the projection just adds a life time
item_type
} else {
Expand All @@ -1100,16 +1100,16 @@ impl<'tcx> TypeVisitor<'tcx> {
}
}
debug!("could not resolve an associated type with concrete type arguments");
gen_arg_type
ty
}
} else {
Ty::new_projection(self.tcx, projection.def_id, specialized_substs)
};
}
if map.is_none() {
return gen_arg_type;
return ty;
}
match gen_arg_type.kind() {
match ty.kind() {
TyKind::Adt(def, args) => {
Ty::new_adt(self.tcx, *def, self.specialize_generic_args(args, map))
}
Expand Down Expand Up @@ -1213,7 +1213,7 @@ impl<'tcx> TypeVisitor<'tcx> {
let closures_being_specialized =
borrowed_closures_being_specialized.deref_mut();
if !closures_being_specialized.insert(*def_id) {
return gen_arg_type;
return ty;
}
}
let specialized_closure =
Expand Down Expand Up @@ -1245,9 +1245,9 @@ impl<'tcx> TypeVisitor<'tcx> {
return gen_arg.expect_ty();
}
}
gen_arg_type
ty
}
_ => gen_arg_type,
_ => ty,
}
}

Expand Down

0 comments on commit d938fcb

Please sign in to comment.