开启RefCell debug_refcell feature查看借用冲突位置

文章目录

  • 背景
  • 分析
  • 解决方法

本文解决两个问题:

  • 开启rust源码库中的feature
  • 开启debug_refcell feature的方法查看 borrow 借用冲突的位置

背景

使用 RefCell 来实现内部可变性是在 Rust 开发中常用的方式,但是当逻辑复杂起来,常常会有可变借用和不可变借用之间的冲突。在默认情况下,Rust只会报错最后冲突的位置,即第7行,而第6行不会在错误堆栈出现。如果逻辑复杂起来,b的位置不在这么明显的位置,根本无从查起。
在这里插入图片描述

分析

查看 borrow() 和 borrow_mut() 的源码,它们分别是调用了 try_borrow() 和 try_borrow_mut(),在 try_borrow() 和 try_borrow_mut() 里面,发现了这么一段代码:

 Some(b) => {
     #[cfg(feature = "debug_refcell")]
     {
         // `borrowed_at` is always the *first* active borrow
         if b.borrow.get() == 1 {
             self.borrowed_at.set(Some(crate::panic::Location::caller()));
         }
     }

     // SAFETY: `BorrowRef` ensures that there is only immutable access
     // to the value while borrowed.
     let value = unsafe { NonNull::new_unchecked(self.value.get()) };
     Ok(Ref { value, borrow: b })
 }
 None => Err(BorrowError {
     // If a borrow occurred, then we must already have an outstanding borrow,
     // so `borrowed_at` will be `Some`
     #[cfg(feature = "debug_refcell")]
     location: self.borrowed_at.get().unwrap(),
 }),

可以看到 RefCell 有 borrowed_at 这么一个字段,当是 Some 并且 b.borrow.get() 是1的时候,设置了 borrowed_at;当是 None 的时候,给 BorrowError 传了 borrowed_at这个参数。

我们可以合理推测,borrowed_at是第一个被借用的"变量"。来看看 RefCell 结构体定义的地方:

pub struct RefCell<T: ?Sized> {
    borrow: Cell<BorrowFlag>,
    // Stores the location of the earliest currently active borrow.
    // This gets updated whenever we go from having zero borrows
    // to having a single borrow. When a borrow occurs, this gets included
    // in the generated `BorrowError`/`BorrowMutError`
    #[cfg(feature = "debug_refcell")]
    borrowed_at: Cell<Option<&'static crate::panic::Location<'static>>>,
    value: UnsafeCell<T>,
}

注释解释的很清楚了,borrowed_at就是最早发生的借用,当借用冲突发生的时候,它可以在错误中生成。

那么就是用 borrowed_at 查看冲突的位置了,但是要用它就需要打开 debug_refcell feature,默认情况下显然没有开启(因为上面的错误信息并没有最早发生借用的位置),而直接在项目的 Cargo.toml 中添加 debug_refcell 是不行的,因为这只是在我们自己的项目中开启feature,rust库是不知道的。

接下来就是要解决怎么在 rust源码库中开启指定 feature。

解决方法

询问 ChatGPT,需要在cargo build的时候编译源码库,并为其指定feature:

cargo +nightly run --target=x86_64-pc-windows-msvc -Zbuild-std -Zbuild-std-features="core/debug_refcell"

这次报错信息出现了最早借用的位置,即第6行。
在这里插入图片描述

这种方式需要使用 nightly 版本的rust编译器

rustup toolchain install nightly
rustup component add rust-src --toolchain nightly-x86_64-pc-windows-msvc
# 验证 nightly 版本是否安装
# 不需要切换到 nightly,上面的命令指定了这次编译的编译器版本是 nightly
rustup toolchain list 

如果你的项目环境是 no_std,需要去指定编译的库(排除std)

cargo +nightly build --release --target thumbv8m.main-none-eabihf -Zbuild-std=core,alloc -Zbuild-std-features="core/debug_refcell"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896693.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

word建立目录以及修改页码

1、为word建立新的目录 &#xff08;1&#xff09;选中word中的标题设置为第几级标题&#xff0c;将所有的标题均设置完成。最后可以鼠标右击标题&#xff0c;对不同的标题字体大小等进行设置。右击-->修改-->格式-->段落 &#xff08;2&#xff09;在word中插入新的…

算法01----移动零(C++)

题目展示 算法原理 我们这里要用到的算法是双指针移动&#xff0c;和我们之前学的快排的核心思想是一样的。我们看看怎么做吧。我会以图片的形式将我的思路告知大家。 这就是整个题目的整体思想算法&#xff0c;大家理解一下&#xff0c;其实这道题目还是很简单的。 代码编写…

【C++ 11】移动构造函数

文章目录 【 1. 问题背景&#xff1a;深拷贝引起的内存开销问题 】【 2. 移动构造函数 】【 3. 左值的移动构造函数: move 实现 】 【 1. 问题背景&#xff1a;深拷贝引起的内存开销问题 】 拷贝构造函数 在 C 11 标准之前&#xff08;C 98/03 标准中&#xff09;&#xff0c;…

Vue脚手架学习 vue脚手架配置代理、插槽、Vuex使用、路由、ElementUi插件库的使用

目录 1.vue脚手架配置代理 1.1 方法一 1.2 方法二 2.插槽 2.1 默认插槽 2.2 具名插槽 2.3 作用域插槽 3.Vuex 3.1 概念 3.2 何时使用&#xff1f; 3.3 搭建vuex环境 3.4 基本使用 3.5 getters的使用 3.6 四个map方法的使用 3.6.1 mapState方法 3.6.2 mapGetter…

LabVIEW中句柄与引用

在LabVIEW中&#xff0c;句柄&#xff08;Handle&#xff09; 是一种用于引用特定资源或对象的标识符。它类似于指针&#xff0c;允许程序在内存中管理和操作复杂的资源&#xff0c;而不需要直接访问资源本身。句柄用于管理动态分配的资源&#xff0c;如队列、文件、网络连接、…

[python flask 数据库ORM操作]

一、链接数据库 我们选择的框架是flask-sqlAlchemy 这个框架是对pymysql的封装。 连接数据库 #导入包 from flask_sqlalchemy import SQLAlchemy #创建flask app对象 app Flask(__name__) #设置配置信息 HOSTNAME "localhost" PORT 3306; USERNAME "root&…

在C++中比大小

关于min()函数和max()函数: min()、max()这两个函数如果需要使用&#xff0c;要在程序头文件中加上<algorithm>库就可以使用这个函数了 #include <algorithm>min()函数是比较数中哪一个数最小&#xff0c;就返回最小的数&#xff0c;而max()函数则是比较数中哪一个…

计算机毕业设计Flask+Vue.js空气质量预测 空气质量可视化 空气质量分析 空气质量爬虫 大数据毕业设计 Hadoop Spark

《FlaskVue.js空气质量预测与可视化系统》开题报告与任务书 一、研究背景与意义 随着工业化进程的加速和城市化水平的不断提高&#xff0c;空气质量问题日益成为全球关注的焦点。空气污染不仅严重影响着人们的身体健康&#xff0c;如增加呼吸系统疾病、心血管疾病等风险&…

商场楼宇室内导航系统

商场楼宇室内导航系统 本文所涉及所有资源均在传知代码平台可获取 文章目录 商场楼宇室内导航系统效果图导航效果图查看信息数据加载加载模型模型选型处理楼层模型绑定店铺创建店铺名称动态显示隐藏2d元素空气墙查看信息楼梯导航效果图 导航效果图 查看信息 数据加载 因为是一…

Java最全面试题->Java主流框架->Srping面试题

Spring面试题 下边是我自己整理的面试题,基本已经很全面了,想要的可以私信我,我会不定期去更新思维导图 哪里不会点哪里 谈谈你对 Spring 的理解? Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能。…

定时开关机功能实现

提示&#xff1a;本文仅仅针对MTK平台实现需求&#xff0c;对其它芯片主控平台暂无借鉴可言 文章目录 需求需求描述实际手机功能图 资料相关说明实现方案修改方案修改内容点内置App修改MtkAlarmManagerService.java 坑点解决总结 需求 实现手机一样的定时开关机功能 需求描述…

计算不停歇,百度沧海数据湖存储加速方案 2.0 设计和实践

本文整理自百度云智峰会 2024 —— 云原生论坛的同名演讲。 今天给大家介绍下百度沧海存储团队在数据湖加速方面的工作进展情况。 数据湖这个概念&#xff0c;从 2012 年产生到现在已经有十余年的时间&#xff0c;每家公司对它内涵的解读都不太一样。但是数据湖的主要存储底座…

具备哪些特质的内外网文件交换系统 才是高科技企业需要的?

高科技企业是指涉及对国家产生深远和积极影响的先进技术的产业集群&#xff0c;它们以持续的创新和高研发投入为核心&#xff0c;推动科技进步和产业升级。高科技企业是市场经济的重要组成&#xff0c;为经济发展和技术进步提供充足动力&#xff0c;因此&#xff0c;高科技企业…

【南开X上海交大】OPUS:效率显著提升的OCC网络

1. 摘要 占据预测任务旨在预测体素化的3D环境中的占据状态&#xff0c;在自动驾驶领域中迅速获得了关注。主流的占据预测方法首先将3D环境离散化为体素网格&#xff0c;然后在这些密集网格上执行分类。然而&#xff0c;样本数据分析显示&#xff0c;大多数体素实际上是未占据的…

《15分钟轻松学Go》教程目录

在AI快速发展的时代&#xff0c;学习Go语言依然很有用。Go语言擅长处理高并发任务&#xff0c;也就是说可以同时处理很多请求&#xff0c;这对于需要快速响应的AI服务非常重要。另外&#xff0c;Go适合用来处理和传输大量数据&#xff0c;非常适合机器学习模型的数据预处理。 …

并查集 --- Java通用模版

什么是并查集 并查集可以解决什么问题&#xff1a;判断两个节点是否在一个集合&#xff0c;也可以将两个节点添加到一个集合中。 并查集常用于处理大规模数据下的元素分组问题&#xff0c;特别是在数据量极大时&#xff0c;使用正常的数据结构可能会导致空间或时间复杂度过高…

2024年10月21日计算机网络,乌蒙第一部分

【互联网数据传输原理 &#xff5c;OSI七层网络参考模型】 https://www.bilibili.com/video/BV1EU4y1v7ju/?share_sourcecopy_web&vd_source476fcb3b552dae37b7e82015a682a972 mac地址相当于是名字&#xff0c;ip地址相当于是住址&#xff0c;端口相当于是发送的东西拿什…

推荐一款功能强大的数据备份工具:Iperius Backup Full

Iperius Backup是一款非常灵活而且功能强大的数据备份工具&#xff0c;程序可以非常好的保护您的文件和数据的安全。支持DAT备份、LTO备份、NAS备份、磁带备份、RDX驱动器、USB备份、并且支持zip压缩和军事级别的AES 256位数据加密技术! 主要特色 云备份 Iperius可以自动地发…

STM32F1+HAL库+FreeTOTS学习18——任务通知

STM32F1HAL库FreeTOTS学习18——任务通知 1. 任务通知1.1 任务通知的引入1.2 任务通知简介1.3 任务通知的优缺点 2. 任务相关API函数2.1 发送任务通知2.1.1 xTaskGenericNotify()2.1.2 xTaskNotifyGive()和xTaskNotifyGiveIndexed()2.1.2 xTaskNotify()和xTaskNotifyIndexed()2…

【LeetCode:910. 最小差值 II + 模拟 + 思维】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…