rust_verify/src/reveal_hide.rs
Line | Count | Source |
1 | | use std::convert::TryInto; |
2 | | use std::sync::Arc; |
3 | | |
4 | | use rustc_hir::{Expr, ExprKind, QPath, def::Res}; |
5 | | use vir::ast::{ExprX, FunX, HeaderExprX}; |
6 | | |
7 | | use crate::{unsupported_err, unsupported_err_unless, util::err_span}; |
8 | | |
9 | | pub(crate) enum RevealHideResult { |
10 | | Expr(vir::ast::Expr), |
11 | | RevealItem(vir::ast::Fun), |
12 | | } |
13 | | |
14 | 45.1k | pub(crate) fn handle_reveal_hide<'ctxt>( |
15 | 45.1k | ctxt: &crate::context::Context<'ctxt>, |
16 | 45.1k | expr: &Expr<'ctxt>, |
17 | 45.1k | args_len: usize, |
18 | 45.1k | args: &Vec<&Expr<'ctxt>>, |
19 | 45.1k | tcx: rustc_middle::ty::TyCtxt<'ctxt>, |
20 | 45.1k | mk_expr: Option<impl Fn(ExprX) -> Result<vir::ast::Expr, vir::ast::VirErr>>, |
21 | 45.1k | ) -> Result<RevealHideResult, vir::ast::VirErr> { |
22 | 45.1k | unsupported_err_unless!(args_len == 2, expr.span, "expected reveal", &args); |
23 | 45.1k | let ExprKind::Block(block, None) = args[0].kind else { |
24 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
25 | | }; |
26 | 45.1k | if block.stmts.len() != 1 || !matches!(block.stmts[0].kind, rustc_hir::StmtKind::Item(_)) { |
27 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
28 | 45.1k | } |
29 | 45.1k | let Some(block_expr) = block.expr.as_ref() else { |
30 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
31 | | }; |
32 | 45.1k | let is_broadcast_use = { |
33 | 45.1k | let expr_attrs = ctxt.tcx.hir_attrs(block_expr.hir_id); |
34 | 45.1k | let expr_vattrs = ctxt.get_verifier_attrs(expr_attrs)?; |
35 | 45.1k | expr_vattrs.broadcast_use_reveal |
36 | | }; |
37 | 45.1k | let ExprKind::Path(QPath::Resolved(None, path)) = &block_expr.kind else { |
38 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
39 | | }; |
40 | 45.1k | let id = { |
41 | 45.1k | let Some(path_map) = |
42 | 45.1k | &*crate::verifier::BODY_HIR_ID_TO_REVEAL_PATH_RES.read().expect("lock failed") |
43 | | else { |
44 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
45 | | }; |
46 | 45.1k | let (ty_res, res) = &path_map[&path.res.def_id()]; |
47 | 45.1k | if let Some(ty_res) = ty_res { |
48 | 5.60k | match res { |
49 | 15 | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => { |
50 | | // `res` has the def_id of the trait function |
51 | | // `ty_res` has the def_id of the type, or is a primitive type |
52 | | // we need to find the impl that contains the non-blanket |
53 | | // implementation of the function for the type |
54 | 15 | let trait_ = tcx.trait_of_assoc(res.def_id()).expect("trait of function"); |
55 | 15 | let ty_ = match ty_res { |
56 | 13 | Res::Def(_, def_id) => tcx.type_of(*def_id).skip_binder(), |
57 | 2 | Res::PrimTy(prim_ty) => crate::util::hir_prim_ty_to_mir_ty(tcx, prim_ty), |
58 | | _ => { |
59 | 0 | unsupported_err!(expr.span, "type {:?} not supported in reveal", ty_res) |
60 | | } |
61 | | }; |
62 | 15 | *tcx.non_blanket_impls_for_ty(trait_, ty_) |
63 | 15 | .find_map(|impl_| { |
64 | 15 | let implementor_ids = &tcx.impl_item_implementor_ids(impl_); |
65 | 15 | implementor_ids.get(&res.def_id()) |
66 | 15 | }) Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideFNtNtCs3IMyNV1CYX4_3vir3ast5ExprXEINtNtCs27Vx93FoQ6z_4core6result6ResultINtNtCsgW8esjfipvk_5alloc4sync3ArcINtB17_12SpannedTypedB15_EEIB2f_NtNtB19_8messages8MessageXEEE0B6_ _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_14fn_call_to_vir0E0E0B6_ Line | Count | Source | 63 | 15 | .find_map(|impl_| { | 64 | 15 | let implementor_ids = &tcx.impl_item_implementor_ids(impl_); | 65 | 15 | implementor_ids.get(&res.def_id()) | 66 | 15 | }) |
Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_29fn_call_or_assoc_const_to_vir0E0E0B6_ |
67 | 15 | .expect("non-blanked impl for ty with def") |
68 | | } |
69 | 5.58k | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(sym) => { |
70 | 5.58k | let Some(def_id) = ty_res.opt_def_id() else { |
71 | 1 | return err_span( |
72 | 1 | expr.span, |
73 | 1 | format!( |
74 | | "`{}` requires clarification, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", |
75 | 1 | sym.as_str() |
76 | | ), |
77 | | ); |
78 | | }; |
79 | 5.58k | let matching_impls: Vec<_> = tcx |
80 | 5.58k | .inherent_impls(def_id) |
81 | 5.58k | .iter() |
82 | 31.9k | .filter_map(|impl_def_id| { |
83 | 31.9k | let ident = rustc_span::symbol::Ident::from_str(sym.as_str()); |
84 | 31.9k | let found = |
85 | 31.9k | tcx.associated_items(*impl_def_id).find_by_ident_and_namespace( |
86 | 31.9k | tcx, |
87 | 31.9k | ident, |
88 | 31.9k | rustc_hir::def::Namespace::ValueNS, |
89 | 31.9k | *impl_def_id, |
90 | | ); |
91 | 31.9k | found.map(|f| f.def_id) |
92 | 31.9k | }) _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideFNtNtCs3IMyNV1CYX4_3vir3ast5ExprXEINtNtCs27Vx93FoQ6z_4core6result6ResultINtNtCsgW8esjfipvk_5alloc4sync3ArcINtB17_12SpannedTypedB15_EEIB2f_NtNtB19_8messages8MessageXEEEs_0B6_ Line | Count | Source | 82 | 2 | .filter_map(|impl_def_id| { | 83 | 2 | let ident = rustc_span::symbol::Ident::from_str(sym.as_str()); | 84 | 2 | let found = | 85 | 2 | tcx.associated_items(*impl_def_id).find_by_ident_and_namespace( | 86 | 2 | tcx, | 87 | 2 | ident, | 88 | 2 | rustc_hir::def::Namespace::ValueNS, | 89 | 2 | *impl_def_id, | 90 | | ); | 91 | 2 | found.map(|f| f.def_id) | 92 | 2 | }) |
_RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_14fn_call_to_vir0E0Es_0B6_ Line | Count | Source | 82 | 31.9k | .filter_map(|impl_def_id| { | 83 | 31.9k | let ident = rustc_span::symbol::Ident::from_str(sym.as_str()); | 84 | 31.9k | let found = | 85 | 31.9k | tcx.associated_items(*impl_def_id).find_by_ident_and_namespace( | 86 | 31.9k | tcx, | 87 | 31.9k | ident, | 88 | 31.9k | rustc_hir::def::Namespace::ValueNS, | 89 | 31.9k | *impl_def_id, | 90 | | ); | 91 | 31.9k | found.map(|f| f.def_id) | 92 | 31.9k | }) |
Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_29fn_call_or_assoc_const_to_vir0E0Es_0B6_ |
93 | 5.58k | .collect(); |
94 | 5.58k | if matching_impls.len() > 1 { |
95 | 0 | return err_span( |
96 | 0 | expr.span, |
97 | 0 | format!( |
98 | | "`{}` is ambiguous, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", |
99 | 0 | sym.as_str() |
100 | | ), |
101 | | ); |
102 | 5.58k | } else if matching_impls.len() == 0 { |
103 | 1 | return err_span(expr.span, format!("`{}` not found", sym.as_str())); |
104 | | } else { |
105 | 5.58k | matching_impls.into_iter().next().unwrap() |
106 | | } |
107 | | } |
108 | | } |
109 | | } else { |
110 | 39.5k | match res { |
111 | 39.5k | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => res.def_id(), |
112 | | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(_) => { |
113 | 0 | unsupported_err!(expr.span, "unexpected reveal", &args); |
114 | | } |
115 | | } |
116 | | } |
117 | | }; |
118 | 45.1k | let path = ctxt.def_id_to_vir_path(id); |
119 | | |
120 | 45.1k | let ExprKind::Lit(fuel_lit) = args[1].kind else { |
121 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); |
122 | | }; |
123 | 45.1k | let span = &ctxt.spans.to_air_span(expr.span); |
124 | 45.1k | let rustc_ast::LitKind::Int(fuel_val, rustc_ast::LitIntType::Unsuffixed) = fuel_lit.node else { |
125 | 0 | return Err(vir::messages::error(span, "Fuel must be a u32 value")); |
126 | | }; |
127 | 45.1k | let fuel_n: u32 = fuel_val |
128 | 45.1k | .get() |
129 | 45.1k | .try_into() |
130 | 45.1k | .map_err(|_| vir::messages::error(span, "Fuel must be a u32 value"))?; Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideFNtNtCs3IMyNV1CYX4_3vir3ast5ExprXEINtNtCs27Vx93FoQ6z_4core6result6ResultINtNtCsgW8esjfipvk_5alloc4sync3ArcINtB17_12SpannedTypedB15_EEIB2f_NtNtB19_8messages8MessageXEEEs0_0B6_ Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_14fn_call_to_vir0E0Es0_0B6_ Unexecuted instantiation: _RNCINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB6_14fn_call_to_vir17verus_item_to_virNCNvB19_29fn_call_or_assoc_const_to_vir0E0Es0_0B6_ |
131 | | |
132 | 45.1k | let fun = Arc::new(FunX { path }); |
133 | 45.1k | if let Some(mk_expr) = mk_expr { |
134 | 43.6k | (if fuel_n == 0 { |
135 | 13 | let header = Arc::new(HeaderExprX::Hide(fun)); |
136 | 13 | mk_expr(ExprX::Header(header)) |
137 | | } else { |
138 | 43.6k | mk_expr(ExprX::Fuel(fun, fuel_n, is_broadcast_use)) |
139 | | }) |
140 | 43.6k | .map(RevealHideResult::Expr) |
141 | | } else { |
142 | 1.51k | assert_eq!(fuel_n, 1); |
143 | | |
144 | 1.51k | Ok(RevealHideResult::RevealItem(fun)) |
145 | | } |
146 | 45.1k | } _RINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideFNtNtCs3IMyNV1CYX4_3vir3ast5ExprXEINtNtCs27Vx93FoQ6z_4core6result6ResultINtNtCsgW8esjfipvk_5alloc4sync3ArcINtB15_12SpannedTypedB13_EEIB2d_NtNtB17_8messages8MessageXEEEB4_ Line | Count | Source | 14 | 1.51k | pub(crate) fn handle_reveal_hide<'ctxt>( | 15 | 1.51k | ctxt: &crate::context::Context<'ctxt>, | 16 | 1.51k | expr: &Expr<'ctxt>, | 17 | 1.51k | args_len: usize, | 18 | 1.51k | args: &Vec<&Expr<'ctxt>>, | 19 | 1.51k | tcx: rustc_middle::ty::TyCtxt<'ctxt>, | 20 | 1.51k | mk_expr: Option<impl Fn(ExprX) -> Result<vir::ast::Expr, vir::ast::VirErr>>, | 21 | 1.51k | ) -> Result<RevealHideResult, vir::ast::VirErr> { | 22 | 1.51k | unsupported_err_unless!(args_len == 2, expr.span, "expected reveal", &args); | 23 | 1.51k | let ExprKind::Block(block, None) = args[0].kind else { | 24 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 25 | | }; | 26 | 1.51k | if block.stmts.len() != 1 || !matches!(block.stmts[0].kind, rustc_hir::StmtKind::Item(_)) { | 27 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 28 | 1.51k | } | 29 | 1.51k | let Some(block_expr) = block.expr.as_ref() else { | 30 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 31 | | }; | 32 | 1.51k | let is_broadcast_use = { | 33 | 1.51k | let expr_attrs = ctxt.tcx.hir_attrs(block_expr.hir_id); | 34 | 1.51k | let expr_vattrs = ctxt.get_verifier_attrs(expr_attrs)?; | 35 | 1.51k | expr_vattrs.broadcast_use_reveal | 36 | | }; | 37 | 1.51k | let ExprKind::Path(QPath::Resolved(None, path)) = &block_expr.kind else { | 38 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 39 | | }; | 40 | 1.51k | let id = { | 41 | 1.51k | let Some(path_map) = | 42 | 1.51k | &*crate::verifier::BODY_HIR_ID_TO_REVEAL_PATH_RES.read().expect("lock failed") | 43 | | else { | 44 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 45 | | }; | 46 | 1.51k | let (ty_res, res) = &path_map[&path.res.def_id()]; | 47 | 1.51k | if let Some(ty_res) = ty_res { | 48 | 2 | match res { | 49 | 0 | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => { | 50 | | // `res` has the def_id of the trait function | 51 | | // `ty_res` has the def_id of the type, or is a primitive type | 52 | | // we need to find the impl that contains the non-blanket | 53 | | // implementation of the function for the type | 54 | 0 | let trait_ = tcx.trait_of_assoc(res.def_id()).expect("trait of function"); | 55 | 0 | let ty_ = match ty_res { | 56 | 0 | Res::Def(_, def_id) => tcx.type_of(*def_id).skip_binder(), | 57 | 0 | Res::PrimTy(prim_ty) => crate::util::hir_prim_ty_to_mir_ty(tcx, prim_ty), | 58 | | _ => { | 59 | 0 | unsupported_err!(expr.span, "type {:?} not supported in reveal", ty_res) | 60 | | } | 61 | | }; | 62 | 0 | *tcx.non_blanket_impls_for_ty(trait_, ty_) | 63 | 0 | .find_map(|impl_| { | 64 | | let implementor_ids = &tcx.impl_item_implementor_ids(impl_); | 65 | | implementor_ids.get(&res.def_id()) | 66 | | }) | 67 | 0 | .expect("non-blanked impl for ty with def") | 68 | | } | 69 | 2 | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(sym) => { | 70 | 2 | let Some(def_id) = ty_res.opt_def_id() else { | 71 | 0 | return err_span( | 72 | 0 | expr.span, | 73 | 0 | format!( | 74 | | "`{}` requires clarification, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", | 75 | 0 | sym.as_str() | 76 | | ), | 77 | | ); | 78 | | }; | 79 | 2 | let matching_impls: Vec<_> = tcx | 80 | 2 | .inherent_impls(def_id) | 81 | 2 | .iter() | 82 | 2 | .filter_map(|impl_def_id| { | 83 | | let ident = rustc_span::symbol::Ident::from_str(sym.as_str()); | 84 | | let found = | 85 | | tcx.associated_items(*impl_def_id).find_by_ident_and_namespace( | 86 | | tcx, | 87 | | ident, | 88 | | rustc_hir::def::Namespace::ValueNS, | 89 | | *impl_def_id, | 90 | | ); | 91 | | found.map(|f| f.def_id) | 92 | | }) | 93 | 2 | .collect(); | 94 | 2 | if matching_impls.len() > 1 { | 95 | 0 | return err_span( | 96 | 0 | expr.span, | 97 | 0 | format!( | 98 | | "`{}` is ambiguous, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", | 99 | 0 | sym.as_str() | 100 | | ), | 101 | | ); | 102 | 2 | } else if matching_impls.len() == 0 { | 103 | 0 | return err_span(expr.span, format!("`{}` not found", sym.as_str())); | 104 | | } else { | 105 | 2 | matching_impls.into_iter().next().unwrap() | 106 | | } | 107 | | } | 108 | | } | 109 | | } else { | 110 | 1.51k | match res { | 111 | 1.51k | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => res.def_id(), | 112 | | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(_) => { | 113 | 0 | unsupported_err!(expr.span, "unexpected reveal", &args); | 114 | | } | 115 | | } | 116 | | } | 117 | | }; | 118 | 1.51k | let path = ctxt.def_id_to_vir_path(id); | 119 | | | 120 | 1.51k | let ExprKind::Lit(fuel_lit) = args[1].kind else { | 121 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 122 | | }; | 123 | 1.51k | let span = &ctxt.spans.to_air_span(expr.span); | 124 | 1.51k | let rustc_ast::LitKind::Int(fuel_val, rustc_ast::LitIntType::Unsuffixed) = fuel_lit.node else { | 125 | 0 | return Err(vir::messages::error(span, "Fuel must be a u32 value")); | 126 | | }; | 127 | 1.51k | let fuel_n: u32 = fuel_val | 128 | 1.51k | .get() | 129 | 1.51k | .try_into() | 130 | 1.51k | .map_err(|_| vir::messages::error(span, "Fuel must be a u32 value"))?; | 131 | | | 132 | 1.51k | let fun = Arc::new(FunX { path }); | 133 | 1.51k | if let Some(mk_expr) = mk_expr { | 134 | 0 | (if fuel_n == 0 { | 135 | 0 | let header = Arc::new(HeaderExprX::Hide(fun)); | 136 | 0 | mk_expr(ExprX::Header(header)) | 137 | | } else { | 138 | 0 | mk_expr(ExprX::Fuel(fun, fuel_n, is_broadcast_use)) | 139 | | }) | 140 | 0 | .map(RevealHideResult::Expr) | 141 | | } else { | 142 | 1.51k | assert_eq!(fuel_n, 1); | 143 | | | 144 | 1.51k | Ok(RevealHideResult::RevealItem(fun)) | 145 | | } | 146 | 1.51k | } |
_RINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB4_14fn_call_to_vir17verus_item_to_virNCNvB17_14fn_call_to_vir0E0EB4_ Line | Count | Source | 14 | 43.6k | pub(crate) fn handle_reveal_hide<'ctxt>( | 15 | 43.6k | ctxt: &crate::context::Context<'ctxt>, | 16 | 43.6k | expr: &Expr<'ctxt>, | 17 | 43.6k | args_len: usize, | 18 | 43.6k | args: &Vec<&Expr<'ctxt>>, | 19 | 43.6k | tcx: rustc_middle::ty::TyCtxt<'ctxt>, | 20 | 43.6k | mk_expr: Option<impl Fn(ExprX) -> Result<vir::ast::Expr, vir::ast::VirErr>>, | 21 | 43.6k | ) -> Result<RevealHideResult, vir::ast::VirErr> { | 22 | 43.6k | unsupported_err_unless!(args_len == 2, expr.span, "expected reveal", &args); | 23 | 43.6k | let ExprKind::Block(block, None) = args[0].kind else { | 24 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 25 | | }; | 26 | 43.6k | if block.stmts.len() != 1 || !matches!(block.stmts[0].kind, rustc_hir::StmtKind::Item(_)) { | 27 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 28 | 43.6k | } | 29 | 43.6k | let Some(block_expr) = block.expr.as_ref() else { | 30 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 31 | | }; | 32 | 43.6k | let is_broadcast_use = { | 33 | 43.6k | let expr_attrs = ctxt.tcx.hir_attrs(block_expr.hir_id); | 34 | 43.6k | let expr_vattrs = ctxt.get_verifier_attrs(expr_attrs)?; | 35 | 43.6k | expr_vattrs.broadcast_use_reveal | 36 | | }; | 37 | 43.6k | let ExprKind::Path(QPath::Resolved(None, path)) = &block_expr.kind else { | 38 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 39 | | }; | 40 | 43.6k | let id = { | 41 | 43.6k | let Some(path_map) = | 42 | 43.6k | &*crate::verifier::BODY_HIR_ID_TO_REVEAL_PATH_RES.read().expect("lock failed") | 43 | | else { | 44 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 45 | | }; | 46 | 43.6k | let (ty_res, res) = &path_map[&path.res.def_id()]; | 47 | 43.6k | if let Some(ty_res) = ty_res { | 48 | 5.60k | match res { | 49 | 15 | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => { | 50 | | // `res` has the def_id of the trait function | 51 | | // `ty_res` has the def_id of the type, or is a primitive type | 52 | | // we need to find the impl that contains the non-blanket | 53 | | // implementation of the function for the type | 54 | 15 | let trait_ = tcx.trait_of_assoc(res.def_id()).expect("trait of function"); | 55 | 15 | let ty_ = match ty_res { | 56 | 13 | Res::Def(_, def_id) => tcx.type_of(*def_id).skip_binder(), | 57 | 2 | Res::PrimTy(prim_ty) => crate::util::hir_prim_ty_to_mir_ty(tcx, prim_ty), | 58 | | _ => { | 59 | 0 | unsupported_err!(expr.span, "type {:?} not supported in reveal", ty_res) | 60 | | } | 61 | | }; | 62 | 15 | *tcx.non_blanket_impls_for_ty(trait_, ty_) | 63 | 15 | .find_map(|impl_| { | 64 | | let implementor_ids = &tcx.impl_item_implementor_ids(impl_); | 65 | | implementor_ids.get(&res.def_id()) | 66 | | }) | 67 | 15 | .expect("non-blanked impl for ty with def") | 68 | | } | 69 | 5.58k | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(sym) => { | 70 | 5.58k | let Some(def_id) = ty_res.opt_def_id() else { | 71 | 1 | return err_span( | 72 | 1 | expr.span, | 73 | 1 | format!( | 74 | | "`{}` requires clarification, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", | 75 | 1 | sym.as_str() | 76 | | ), | 77 | | ); | 78 | | }; | 79 | 5.58k | let matching_impls: Vec<_> = tcx | 80 | 5.58k | .inherent_impls(def_id) | 81 | 5.58k | .iter() | 82 | 5.58k | .filter_map(|impl_def_id| { | 83 | | let ident = rustc_span::symbol::Ident::from_str(sym.as_str()); | 84 | | let found = | 85 | | tcx.associated_items(*impl_def_id).find_by_ident_and_namespace( | 86 | | tcx, | 87 | | ident, | 88 | | rustc_hir::def::Namespace::ValueNS, | 89 | | *impl_def_id, | 90 | | ); | 91 | | found.map(|f| f.def_id) | 92 | | }) | 93 | 5.58k | .collect(); | 94 | 5.58k | if matching_impls.len() > 1 { | 95 | 0 | return err_span( | 96 | 0 | expr.span, | 97 | 0 | format!( | 98 | | "`{}` is ambiguous, use the universal function call syntax to disambiguate (`<Type as Trait>::function`)", | 99 | 0 | sym.as_str() | 100 | | ), | 101 | | ); | 102 | 5.58k | } else if matching_impls.len() == 0 { | 103 | 1 | return err_span(expr.span, format!("`{}` not found", sym.as_str())); | 104 | | } else { | 105 | 5.58k | matching_impls.into_iter().next().unwrap() | 106 | | } | 107 | | } | 108 | | } | 109 | | } else { | 110 | 38.0k | match res { | 111 | 38.0k | crate::hir_hide_reveal_rewrite::ResOrSymbol::Res(res) => res.def_id(), | 112 | | crate::hir_hide_reveal_rewrite::ResOrSymbol::Symbol(_) => { | 113 | 0 | unsupported_err!(expr.span, "unexpected reveal", &args); | 114 | | } | 115 | | } | 116 | | } | 117 | | }; | 118 | 43.6k | let path = ctxt.def_id_to_vir_path(id); | 119 | | | 120 | 43.6k | let ExprKind::Lit(fuel_lit) = args[1].kind else { | 121 | 0 | unsupported_err!(expr.span, "invalid reveal", &args); | 122 | | }; | 123 | 43.6k | let span = &ctxt.spans.to_air_span(expr.span); | 124 | 43.6k | let rustc_ast::LitKind::Int(fuel_val, rustc_ast::LitIntType::Unsuffixed) = fuel_lit.node else { | 125 | 0 | return Err(vir::messages::error(span, "Fuel must be a u32 value")); | 126 | | }; | 127 | 43.6k | let fuel_n: u32 = fuel_val | 128 | 43.6k | .get() | 129 | 43.6k | .try_into() | 130 | 43.6k | .map_err(|_| vir::messages::error(span, "Fuel must be a u32 value"))?; | 131 | | | 132 | 43.6k | let fun = Arc::new(FunX { path }); | 133 | 43.6k | if let Some(mk_expr) = mk_expr { | 134 | 43.6k | (if fuel_n == 0 { | 135 | 13 | let header = Arc::new(HeaderExprX::Hide(fun)); | 136 | 13 | mk_expr(ExprX::Header(header)) | 137 | | } else { | 138 | 43.6k | mk_expr(ExprX::Fuel(fun, fuel_n, is_broadcast_use)) | 139 | | }) | 140 | 43.6k | .map(RevealHideResult::Expr) | 141 | | } else { | 142 | 0 | assert_eq!(fuel_n, 1); | 143 | | | 144 | 0 | Ok(RevealHideResult::RevealItem(fun)) | 145 | | } | 146 | 43.6k | } |
Unexecuted instantiation: _RINvNtCs1ktLv1mxY4I_11rust_verify11reveal_hide18handle_reveal_hideNCINvNtB4_14fn_call_to_vir17verus_item_to_virNCNvB17_29fn_call_or_assoc_const_to_vir0E0EB4_ |