Skip to content

Commit a90f8f0

Browse files
author
AMG
committed
Merge branch 'master' of https://github.com/amg98/rust
2 parents abd8ffd + 37fb69c commit a90f8f0

File tree

260 files changed

+3737
-1892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+3737
-1892
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,9 @@ dependencies = [
710710

711711
[[package]]
712712
name = "compiletest_rs"
713-
version = "0.7.0"
713+
version = "0.7.1"
714714
source = "registry+https://github.com/rust-lang/crates.io-index"
715-
checksum = "64698e5e2435db061a85e6320af12c30c5fd88eb84b35d2c1e03ce4f143255ca"
715+
checksum = "29843cb8d351febf86557681d049d1e1652b81a086a190fa1173c07fd17fbf83"
716716
dependencies = [
717717
"diff",
718718
"filetime",
@@ -1900,9 +1900,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
19001900

19011901
[[package]]
19021902
name = "libc"
1903-
version = "0.2.103"
1903+
version = "0.2.106"
19041904
source = "registry+https://github.com/rust-lang/crates.io-index"
1905-
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
1905+
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
19061906
dependencies = [
19071907
"rustc-std-workspace-core",
19081908
]

compiler/rustc_ast/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
The `rustc_ast` crate contains those things concerned purely with syntax
2-
– that is, the AST ("abstract syntax tree"), parser, pretty-printer,
3-
lexer, macro expander, and utilities for traversing ASTs.
2+
– that is, the AST ("abstract syntax tree"), along with some definitions for tokens and token streams, data structures/traits for mutating ASTs, and shared definitions for other AST-related parts of the compiler (like the lexer and macro-expansion).
43

54
For more information about how these things work in rustc, see the
65
rustc dev guide:

compiler/rustc_ast/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! The Rust parser and macro expander.
1+
//! The Rust Abstract Syntax Tree (AST).
22
//!
33
//! # Note
44
//!

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,10 @@ where
9494
}
9595
}
9696

97-
fn address_of_allows_mutation(&self, mt: mir::Mutability, place: mir::Place<'tcx>) -> bool {
98-
match mt {
99-
mir::Mutability::Mut => true,
100-
mir::Mutability::Not => self.shared_borrow_allows_mutation(place),
101-
}
97+
fn address_of_allows_mutation(&self, _mt: mir::Mutability, _place: mir::Place<'tcx>) -> bool {
98+
// Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
99+
// it might allow mutation until resolution of #56604.
100+
true
102101
}
103102

104103
fn ref_allows_mutation(&self, kind: mir::BorrowKind, place: mir::Place<'tcx>) -> bool {
@@ -110,6 +109,15 @@ where
110109
}
111110
}
112111

112+
/// `&` only allow mutation if the borrowed place is `!Freeze`.
113+
///
114+
/// This assumes that it is UB to take the address of a struct field whose type is
115+
/// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
116+
/// that same struct whose type is `!Freeze`. If we decide that this is not UB, we will
117+
/// have to check the type of the borrowed **local** instead of the borrowed **place**
118+
/// below. See [rust-lang/unsafe-code-guidelines#134].
119+
///
120+
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
113121
fn shared_borrow_allows_mutation(&self, place: mir::Place<'tcx>) -> bool {
114122
!place
115123
.ty(self.ccx.body, self.ccx.tcx)

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
77
use crate::infer::lexical_region_resolve::RegionResolutionError;
88
use crate::infer::SubregionOrigin;
99

10-
use rustc_errors::{struct_span_err, ErrorReported};
10+
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
11+
use rustc_hir as hir;
12+
use rustc_hir::{GenericParamKind, Ty};
13+
use rustc_middle::ty::Region;
1114

1215
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1316
/// Print the error message for lifetime errors when both the concerned regions are anonymous.
@@ -160,11 +163,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
160163
}
161164
};
162165

163-
let mut e = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch");
166+
let mut err = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch");
164167

165-
e.span_label(span_1, main_label);
166-
e.span_label(span_2, String::new());
167-
e.span_label(span, span_label);
168+
err.span_label(span_1, main_label);
169+
err.span_label(span_2, String::new());
170+
err.span_label(span, span_label);
171+
172+
self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err);
168173

169174
if let Some(t) = future_return_type {
170175
let snip = self
@@ -178,14 +183,87 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
178183
(_, "") => None,
179184
_ => Some(s),
180185
})
181-
.unwrap_or("{unnamed_type}".to_string());
186+
.unwrap_or_else(|| "{unnamed_type}".to_string());
182187

183-
e.span_label(
188+
err.span_label(
184189
t.span,
185190
&format!("this `async fn` implicitly returns an `impl Future<Output = {}>`", snip),
186191
);
187192
}
188-
e.emit();
193+
err.emit();
189194
Some(ErrorReported)
190195
}
196+
197+
fn suggest_adding_lifetime_params(
198+
&self,
199+
sub: Region<'tcx>,
200+
ty_sup: &Ty<'_>,
201+
ty_sub: &Ty<'_>,
202+
err: &mut DiagnosticBuilder<'_>,
203+
) {
204+
if let (
205+
hir::Ty { kind: hir::TyKind::Rptr(lifetime_sub, _), .. },
206+
hir::Ty { kind: hir::TyKind::Rptr(lifetime_sup, _), .. },
207+
) = (ty_sub, ty_sup)
208+
{
209+
if lifetime_sub.name.is_elided() && lifetime_sup.name.is_elided() {
210+
if let Some(anon_reg) = self.tcx().is_suitable_region(sub) {
211+
let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
212+
if let hir::Node::Item(&hir::Item {
213+
kind: hir::ItemKind::Fn(_, ref generics, ..),
214+
..
215+
}) = self.tcx().hir().get(hir_id)
216+
{
217+
let (suggestion_param_name, introduce_new) = generics
218+
.params
219+
.iter()
220+
.find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
221+
.and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
222+
.map(|name| (name, false))
223+
.unwrap_or_else(|| ("'a".to_string(), true));
224+
225+
let mut suggestions = vec![
226+
if let hir::LifetimeName::Underscore = lifetime_sub.name {
227+
(lifetime_sub.span, suggestion_param_name.clone())
228+
} else {
229+
(
230+
lifetime_sub.span.shrink_to_hi(),
231+
suggestion_param_name.clone() + " ",
232+
)
233+
},
234+
if let hir::LifetimeName::Underscore = lifetime_sup.name {
235+
(lifetime_sup.span, suggestion_param_name.clone())
236+
} else {
237+
(
238+
lifetime_sup.span.shrink_to_hi(),
239+
suggestion_param_name.clone() + " ",
240+
)
241+
},
242+
];
243+
244+
if introduce_new {
245+
let new_param_suggestion = match &generics.params {
246+
[] => (generics.span, format!("<{}>", suggestion_param_name)),
247+
[first, ..] => (
248+
first.span.shrink_to_lo(),
249+
format!("{}, ", suggestion_param_name),
250+
),
251+
};
252+
253+
suggestions.push(new_param_suggestion);
254+
}
255+
256+
err.multipart_suggestion(
257+
"consider introducing a named lifetime parameter",
258+
suggestions,
259+
Applicability::MaybeIncorrect,
260+
);
261+
err.note(
262+
"each elided lifetime in input position becomes a distinct lifetime",
263+
);
264+
}
265+
}
266+
}
267+
}
268+
}
191269
}

compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs

Lines changed: 15 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,26 @@ use super::*;
33
use crate::{AnalysisDomain, GenKill, GenKillAnalysis};
44
use rustc_middle::mir::visit::Visitor;
55
use rustc_middle::mir::*;
6-
use rustc_middle::ty::{ParamEnv, TyCtxt};
7-
use rustc_span::DUMMY_SP;
8-
9-
pub type MaybeMutBorrowedLocals<'mir, 'tcx> = MaybeBorrowedLocals<MutBorrow<'mir, 'tcx>>;
106

117
/// A dataflow analysis that tracks whether a pointer or reference could possibly exist that points
128
/// to a given local.
139
///
14-
/// The `K` parameter determines what kind of borrows are tracked. By default,
15-
/// `MaybeBorrowedLocals` looks for *any* borrow of a local. If you are only interested in borrows
16-
/// that might allow mutation, use the `MaybeMutBorrowedLocals` type alias instead.
17-
///
1810
/// At present, this is used as a very limited form of alias analysis. For example,
1911
/// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
20-
/// immovable generators. `MaybeMutBorrowedLocals` is used during const checking to prove that a
21-
/// local has not been mutated via indirect assignment (e.g., `*p = 42`), the side-effects of a
22-
/// function call or inline assembly.
23-
pub struct MaybeBorrowedLocals<K = AnyBorrow> {
24-
kind: K,
12+
/// immovable generators.
13+
pub struct MaybeBorrowedLocals {
2514
ignore_borrow_on_drop: bool,
2615
}
2716

2817
impl MaybeBorrowedLocals {
2918
/// A dataflow analysis that records whether a pointer or reference exists that may alias the
3019
/// given local.
3120
pub fn all_borrows() -> Self {
32-
MaybeBorrowedLocals { kind: AnyBorrow, ignore_borrow_on_drop: false }
33-
}
34-
}
35-
36-
impl MaybeMutBorrowedLocals<'mir, 'tcx> {
37-
/// A dataflow analysis that records whether a pointer or reference exists that may *mutably*
38-
/// alias the given local.
39-
///
40-
/// This includes `&mut` and pointers derived from an `&mut`, as well as shared borrows of
41-
/// types with interior mutability.
42-
pub fn mut_borrows_only(
43-
tcx: TyCtxt<'tcx>,
44-
body: &'mir mir::Body<'tcx>,
45-
param_env: ParamEnv<'tcx>,
46-
) -> Self {
47-
MaybeBorrowedLocals {
48-
kind: MutBorrow { body, tcx, param_env },
49-
ignore_borrow_on_drop: false,
50-
}
21+
MaybeBorrowedLocals { ignore_borrow_on_drop: false }
5122
}
5223
}
5324

54-
impl<K> MaybeBorrowedLocals<K> {
25+
impl MaybeBorrowedLocals {
5526
/// During dataflow analysis, ignore the borrow that may occur when a place is dropped.
5627
///
5728
/// Drop terminators may call custom drop glue (`Drop::drop`), which takes `&mut self` as a
@@ -69,21 +40,14 @@ impl<K> MaybeBorrowedLocals<K> {
6940
MaybeBorrowedLocals { ignore_borrow_on_drop: true, ..self }
7041
}
7142

72-
fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T, K> {
73-
TransferFunction {
74-
kind: &self.kind,
75-
trans,
76-
ignore_borrow_on_drop: self.ignore_borrow_on_drop,
77-
}
43+
fn transfer_function<'a, T>(&'a self, trans: &'a mut T) -> TransferFunction<'a, T> {
44+
TransferFunction { trans, ignore_borrow_on_drop: self.ignore_borrow_on_drop }
7845
}
7946
}
8047

81-
impl<K> AnalysisDomain<'tcx> for MaybeBorrowedLocals<K>
82-
where
83-
K: BorrowAnalysisKind<'tcx>,
84-
{
48+
impl AnalysisDomain<'tcx> for MaybeBorrowedLocals {
8549
type Domain = BitSet<Local>;
86-
const NAME: &'static str = K::ANALYSIS_NAME;
50+
const NAME: &'static str = "maybe_borrowed_locals";
8751

8852
fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
8953
// bottom = unborrowed
@@ -95,10 +59,7 @@ where
9559
}
9660
}
9761

98-
impl<K> GenKillAnalysis<'tcx> for MaybeBorrowedLocals<K>
99-
where
100-
K: BorrowAnalysisKind<'tcx>,
101-
{
62+
impl GenKillAnalysis<'tcx> for MaybeBorrowedLocals {
10263
type Idx = Local;
10364

10465
fn statement_effect(
@@ -131,16 +92,14 @@ where
13192
}
13293

13394
/// A `Visitor` that defines the transfer function for `MaybeBorrowedLocals`.
134-
struct TransferFunction<'a, T, K> {
95+
struct TransferFunction<'a, T> {
13596
trans: &'a mut T,
136-
kind: &'a K,
13797
ignore_borrow_on_drop: bool,
13898
}
13999

140-
impl<T, K> Visitor<'tcx> for TransferFunction<'a, T, K>
100+
impl<T> Visitor<'tcx> for TransferFunction<'a, T>
141101
where
142102
T: GenKill<Local>,
143-
K: BorrowAnalysisKind<'tcx>,
144103
{
145104
fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) {
146105
self.super_statement(stmt, location);
@@ -156,14 +115,14 @@ where
156115
self.super_rvalue(rvalue, location);
157116

158117
match rvalue {
159-
mir::Rvalue::AddressOf(mt, borrowed_place) => {
160-
if !borrowed_place.is_indirect() && self.kind.in_address_of(*mt, *borrowed_place) {
118+
mir::Rvalue::AddressOf(_mt, borrowed_place) => {
119+
if !borrowed_place.is_indirect() {
161120
self.trans.gen(borrowed_place.local);
162121
}
163122
}
164123

165-
mir::Rvalue::Ref(_, kind, borrowed_place) => {
166-
if !borrowed_place.is_indirect() && self.kind.in_ref(*kind, *borrowed_place) {
124+
mir::Rvalue::Ref(_, _kind, borrowed_place) => {
125+
if !borrowed_place.is_indirect() {
167126
self.trans.gen(borrowed_place.local);
168127
}
169128
}
@@ -211,64 +170,3 @@ where
211170
}
212171
}
213172
}
214-
215-
pub struct AnyBorrow;
216-
217-
pub struct MutBorrow<'mir, 'tcx> {
218-
tcx: TyCtxt<'tcx>,
219-
body: &'mir Body<'tcx>,
220-
param_env: ParamEnv<'tcx>,
221-
}
222-
223-
impl MutBorrow<'mir, 'tcx> {
224-
/// `&` and `&raw` only allow mutation if the borrowed place is `!Freeze`.
225-
///
226-
/// This assumes that it is UB to take the address of a struct field whose type is
227-
/// `Freeze`, then use pointer arithmetic to derive a pointer to a *different* field of
228-
/// that same struct whose type is `!Freeze`. If we decide that this is not UB, we will
229-
/// have to check the type of the borrowed **local** instead of the borrowed **place**
230-
/// below. See [rust-lang/unsafe-code-guidelines#134].
231-
///
232-
/// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134
233-
fn shared_borrow_allows_mutation(&self, place: Place<'tcx>) -> bool {
234-
!place.ty(self.body, self.tcx).ty.is_freeze(self.tcx.at(DUMMY_SP), self.param_env)
235-
}
236-
}
237-
238-
pub trait BorrowAnalysisKind<'tcx> {
239-
const ANALYSIS_NAME: &'static str;
240-
241-
fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool;
242-
fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool;
243-
}
244-
245-
impl BorrowAnalysisKind<'tcx> for AnyBorrow {
246-
const ANALYSIS_NAME: &'static str = "maybe_borrowed_locals";
247-
248-
fn in_ref(&self, _: mir::BorrowKind, _: Place<'_>) -> bool {
249-
true
250-
}
251-
fn in_address_of(&self, _: Mutability, _: Place<'_>) -> bool {
252-
true
253-
}
254-
}
255-
256-
impl BorrowAnalysisKind<'tcx> for MutBorrow<'mir, 'tcx> {
257-
const ANALYSIS_NAME: &'static str = "maybe_mut_borrowed_locals";
258-
259-
fn in_ref(&self, kind: mir::BorrowKind, place: Place<'tcx>) -> bool {
260-
match kind {
261-
mir::BorrowKind::Mut { .. } => true,
262-
mir::BorrowKind::Shared | mir::BorrowKind::Shallow | mir::BorrowKind::Unique => {
263-
self.shared_borrow_allows_mutation(place)
264-
}
265-
}
266-
}
267-
268-
fn in_address_of(&self, mt: Mutability, place: Place<'tcx>) -> bool {
269-
match mt {
270-
Mutability::Mut => true,
271-
Mutability::Not => self.shared_borrow_allows_mutation(place),
272-
}
273-
}
274-
}

0 commit comments

Comments
 (0)