Skip to content

Commit 8256e97

Browse files
committed
Auto merge of #97622 - JohnTitor:rollup-4qoxrjn, r=JohnTitor
Rollup of 9 pull requests Successful merges: - #94647 (Expose `get_many_mut` and `get_many_unchecked_mut` to HashMap) - #97216 (Ensure we never consider the null pointer dereferencable) - #97399 (simplify code of finding arg index in `opt_const_param_of`) - #97470 (rustdoc: add more test coverage) - #97498 (Corrected EBNF grammar for from_str) - #97562 (Fix comment in `poly_project_and_unify_type`) - #97580 (Add regression test for #71546) - #97611 (Tweak insert docs) - #97616 (Remove an unnecessary `Option`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 395a09c + 85fdef0 commit 8256e97

File tree

15 files changed

+257
-59
lines changed

15 files changed

+257
-59
lines changed

compiler/rustc_const_eval/src/interpret/memory.rs

+4
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
441441
msg,
442442
})
443443
}
444+
// Ensure we never consider the null pointer dereferencable.
445+
if M::PointerTag::OFFSET_IS_ADDR {
446+
assert_ne!(ptr.addr(), Size::ZERO);
447+
}
444448
// Test align. Check this last; if both bounds and alignment are violated
445449
// we want the error to be about the bounds.
446450
if let Some(align) = align {

compiler/rustc_data_structures/src/sso/set.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,10 @@ impl<T: Eq + Hash> SsoHashSet<T> {
126126

127127
/// Adds a value to the set.
128128
///
129-
/// If the set did not have this value present, `true` is returned.
129+
/// Returns whether the value was newly inserted. That is:
130130
///
131-
/// If the set did have this value present, `false` is returned.
131+
/// - If the set did not previously contain this value, `true` is returned.
132+
/// - If the set already contained this value, `false` is returned.
132133
#[inline]
133134
pub fn insert(&mut self, elem: T) -> bool {
134135
self.map.insert(elem, ()).is_none()

compiler/rustc_trait_selection/src/traits/project.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,28 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
145145
}
146146
}
147147

148-
/// Takes the place of a
148+
/// States returned from `poly_project_and_unify_type`. Takes the place
149+
/// of the old return type, which was:
150+
/// ```ignore (not-rust)
149151
/// Result<
150152
/// Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
151153
/// MismatchedProjectionTypes<'tcx>,
152154
/// >
155+
/// ```
153156
pub(super) enum ProjectAndUnifyResult<'tcx> {
157+
/// The projection bound holds subject to the given obligations. If the
158+
/// projection cannot be normalized because the required trait bound does
159+
/// not hold, this is returned, with `obligations` being a predicate that
160+
/// cannot be proven.
154161
Holds(Vec<PredicateObligation<'tcx>>),
162+
/// The projection cannot be normalized due to ambiguity. Resolving some
163+
/// inference variables in the projection may fix this.
155164
FailedNormalization,
165+
/// The project cannot be normalized because `poly_project_and_unify_type`
166+
/// is called recursively while normalizing the same projection.
156167
Recursive,
168+
// the projection can be normalized, but is not equal to the expected type.
169+
// Returns the type error that arose from the mismatch.
157170
MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
158171
}
159172

@@ -163,19 +176,6 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
163176
/// ```
164177
/// If successful, this may result in additional obligations. Also returns
165178
/// the projection cache key used to track these additional obligations.
166-
///
167-
/// ## Returns
168-
///
169-
/// - `Err(_)`: the projection can be normalized, but is not equal to the
170-
/// expected type.
171-
/// - `Ok(Err(InProgress))`: this is called recursively while normalizing
172-
/// the same projection.
173-
/// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity
174-
/// (resolving some inference variables in the projection may fix this).
175-
/// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to
176-
/// the given obligations. If the projection cannot be normalized because
177-
/// the required trait bound doesn't hold this returned with `obligations`
178-
/// being a predicate that cannot be proven.
179179
#[instrument(level = "debug", skip(selcx))]
180180
pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
181181
selcx: &mut SelectionContext<'cx, 'tcx>,

compiler/rustc_trait_selection/src/traits/wf.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,17 @@ pub fn trait_obligations<'a, 'tcx>(
8181
body_id: hir::HirId,
8282
trait_ref: &ty::TraitRef<'tcx>,
8383
span: Span,
84-
item: Option<&'tcx hir::Item<'tcx>>,
84+
item: &'tcx hir::Item<'tcx>,
8585
) -> Vec<traits::PredicateObligation<'tcx>> {
86-
let mut wf =
87-
WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item };
86+
let mut wf = WfPredicates {
87+
infcx,
88+
param_env,
89+
body_id,
90+
span,
91+
out: vec![],
92+
recursion_depth: 0,
93+
item: Some(item),
94+
};
8895
wf.compute_trait_ref(trait_ref, Elaborate::All);
8996
debug!(obligations = ?wf.out);
9097
wf.normalize()

compiler/rustc_typeck/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ fn check_impl<'tcx>(
12281228
fcx.body_id,
12291229
&trait_ref,
12301230
ast_trait_ref.path.span,
1231-
Some(item),
1231+
item,
12321232
);
12331233
debug!(?obligations);
12341234
for obligation in obligations {

compiler/rustc_typeck/src/collect/type_of.rs

+16-31
Original file line numberDiff line numberDiff line change
@@ -161,38 +161,23 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
161161
// We've encountered an `AnonConst` in some path, so we need to
162162
// figure out which generic parameter it corresponds to and return
163163
// the relevant type.
164-
let filtered = path.segments.iter().find_map(|seg| {
165-
seg.args?
166-
.args
164+
let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| {
165+
let args = seg.args?;
166+
args.args
167+
.iter()
168+
.filter(|arg| arg.is_ty_or_const())
169+
.position(|arg| arg.id() == hir_id)
170+
.map(|index| (index, seg)).or_else(|| args.bindings
167171
.iter()
168-
.filter(|arg| arg.is_ty_or_const())
169-
.position(|arg| arg.id() == hir_id)
170-
.map(|index| (index, seg))
171-
});
172-
173-
// FIXME(associated_const_generics): can we blend this with iteration above?
174-
let (arg_index, segment) = match filtered {
175-
None => {
176-
let binding_filtered = path.segments.iter().find_map(|seg| {
177-
seg.args?
178-
.bindings
179-
.iter()
180-
.filter_map(TypeBinding::opt_const)
181-
.position(|ct| ct.hir_id == hir_id)
182-
.map(|idx| (idx, seg))
183-
});
184-
match binding_filtered {
185-
Some(inner) => inner,
186-
None => {
187-
tcx.sess.delay_span_bug(
188-
tcx.def_span(def_id),
189-
"no arg matching AnonConst in path",
190-
);
191-
return None;
192-
}
193-
}
194-
}
195-
Some(inner) => inner,
172+
.filter_map(TypeBinding::opt_const)
173+
.position(|ct| ct.hir_id == hir_id)
174+
.map(|idx| (idx, seg)))
175+
}) else {
176+
tcx.sess.delay_span_bug(
177+
tcx.def_span(def_id),
178+
"no arg matching AnonConst in path",
179+
);
180+
return None;
196181
};
197182

198183
// Try to use the segment resolution if it is valid, otherwise we

library/alloc/src/collections/btree/set.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -770,10 +770,14 @@ impl<T> BTreeSet<T> {
770770

771771
/// Adds a value to the set.
772772
///
773-
/// If the set did not have an equal element present, `true` is returned.
773+
/// Returns whether the value was newly inserted. That is:
774774
///
775-
/// If the set did have an equal element present, `false` is returned, and
776-
/// the entry is not updated. See the [module-level documentation] for more.
775+
/// - If the set did not previously contain an equal value, `true` is
776+
/// returned.
777+
/// - If the set already contained an equal value, `false` is returned, and
778+
/// the entry is not updated.
779+
///
780+
/// See the [module-level documentation] for more.
777781
///
778782
/// [module-level documentation]: index.html#insert-and-complex-keys
779783
///

library/core/src/num/dec2flt/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ macro_rules! from_str_float_impl {
126126
/// ```txt
127127
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
128128
/// Number ::= ( Digit+ |
129-
/// '.' Digit* |
130129
/// Digit+ '.' Digit* |
131130
/// Digit* '.' Digit+ ) Exp?
132131
/// Exp ::= 'e' Sign? Digit+

library/std/src/collections/hash/map.rs

+113
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,119 @@ where
896896
self.base.get_key_value(k)
897897
}
898898

899+
/// Attempts to get mutable references to `N` values in the map at once.
900+
///
901+
/// Returns an array of length `N` with the results of each query. For soundness, at most one
902+
/// mutable reference will be returned to any value. `None` will be returned if any of the
903+
/// keys are duplicates or missing.
904+
///
905+
/// # Examples
906+
///
907+
/// ```
908+
/// #![feature(map_many_mut)]
909+
/// use std::collections::HashMap;
910+
///
911+
/// let mut libraries = HashMap::new();
912+
/// libraries.insert("Bodleian Library".to_string(), 1602);
913+
/// libraries.insert("Athenæum".to_string(), 1807);
914+
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
915+
/// libraries.insert("Library of Congress".to_string(), 1800);
916+
///
917+
/// let got = libraries.get_many_mut([
918+
/// "Athenæum",
919+
/// "Library of Congress",
920+
/// ]);
921+
/// assert_eq!(
922+
/// got,
923+
/// Some([
924+
/// &mut 1807,
925+
/// &mut 1800,
926+
/// ]),
927+
/// );
928+
///
929+
/// // Missing keys result in None
930+
/// let got = libraries.get_many_mut([
931+
/// "Athenæum",
932+
/// "New York Public Library",
933+
/// ]);
934+
/// assert_eq!(got, None);
935+
///
936+
/// // Duplicate keys result in None
937+
/// let got = libraries.get_many_mut([
938+
/// "Athenæum",
939+
/// "Athenæum",
940+
/// ]);
941+
/// assert_eq!(got, None);
942+
/// ```
943+
#[inline]
944+
#[unstable(feature = "map_many_mut", issue = "97601")]
945+
pub fn get_many_mut<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
946+
where
947+
K: Borrow<Q>,
948+
Q: Hash + Eq,
949+
{
950+
self.base.get_many_mut(ks)
951+
}
952+
953+
/// Attempts to get mutable references to `N` values in the map at once, without validating that
954+
/// the values are unique.
955+
///
956+
/// Returns an array of length `N` with the results of each query. `None` will be returned if
957+
/// any of the keys are missing.
958+
///
959+
/// For a safe alternative see [`get_many_mut`](Self::get_many_mut).
960+
///
961+
/// # Safety
962+
///
963+
/// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
964+
/// references are not used.
965+
///
966+
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
967+
///
968+
/// # Examples
969+
///
970+
/// ```
971+
/// #![feature(map_many_mut)]
972+
/// use std::collections::HashMap;
973+
///
974+
/// let mut libraries = HashMap::new();
975+
/// libraries.insert("Bodleian Library".to_string(), 1602);
976+
/// libraries.insert("Athenæum".to_string(), 1807);
977+
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
978+
/// libraries.insert("Library of Congress".to_string(), 1800);
979+
///
980+
/// let got = libraries.get_many_mut([
981+
/// "Athenæum",
982+
/// "Library of Congress",
983+
/// ]);
984+
/// assert_eq!(
985+
/// got,
986+
/// Some([
987+
/// &mut 1807,
988+
/// &mut 1800,
989+
/// ]),
990+
/// );
991+
///
992+
/// // Missing keys result in None
993+
/// let got = libraries.get_many_mut([
994+
/// "Athenæum",
995+
/// "New York Public Library",
996+
/// ]);
997+
/// assert_eq!(got, None);
998+
/// ```
999+
#[inline]
1000+
#[unstable(feature = "map_many_mut", issue = "97601")]
1001+
pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
1002+
&mut self,
1003+
ks: [&Q; N],
1004+
) -> Option<[&'_ mut V; N]>
1005+
where
1006+
K: Borrow<Q>,
1007+
Q: Hash + Eq,
1008+
{
1009+
self.base.get_many_unchecked_mut(ks)
1010+
}
1011+
8991012
/// Returns `true` if the map contains a value for the specified key.
9001013
///
9011014
/// The key may be any borrowed form of the map's key type, but

library/std/src/collections/hash/set.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -858,9 +858,10 @@ where
858858

859859
/// Adds a value to the set.
860860
///
861-
/// If the set did not have this value present, `true` is returned.
861+
/// Returns whether the value was newly inserted. That is:
862862
///
863-
/// If the set did have this value present, `false` is returned.
863+
/// - If the set did not previously contain this value, `true` is returned.
864+
/// - If the set already contained this value, `false` is returned.
864865
///
865866
/// # Examples
866867
///
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
pub mod my_trait {
2+
pub trait MyTrait {
3+
fn my_fn(&self) -> Self;
4+
}
5+
}
6+
7+
pub mod prelude {
8+
#[doc(inline)]
9+
pub use crate::my_trait::MyTrait;
10+
}
11+
12+
pub struct SomeStruct;
13+
14+
impl my_trait::MyTrait for SomeStruct {
15+
fn my_fn(&self) -> SomeStruct {
16+
SomeStruct
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// aux-build:implementors_inline.rs
2+
// build-aux-docs
3+
// ignore-cross-compile
4+
5+
extern crate implementors_inline;
6+
7+
// @!has implementors/implementors_js/trait.MyTrait.js
8+
// @has implementors/implementors_inline/my_trait/trait.MyTrait.js
9+
// @!has implementors/implementors_inline/prelude/trait.MyTrait.js
10+
// @has implementors_inline/my_trait/trait.MyTrait.html
11+
// @has - '//script/@src' '../../implementors/implementors_inline/my_trait/trait.MyTrait.js'
12+
// @has implementors_js/trait.MyTrait.html
13+
// @has - '//script/@src' '../implementors/implementors_inline/my_trait/trait.MyTrait.js'
14+
/// When re-exporting this trait, the HTML will be inlined,
15+
/// but, vitally, the JavaScript will be located only at the
16+
/// one canonical path.
17+
pub use implementors_inline::prelude::MyTrait;
18+
19+
pub struct OtherStruct;
20+
21+
impl MyTrait for OtherStruct {
22+
fn my_fn(&self) -> OtherStruct {
23+
OtherStruct
24+
}
25+
}
+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
#![allow(rustdoc::broken_intra_doc_links)]
1+
#![forbid(rustdoc::broken_intra_doc_links)]
22

33
//! Email me at <[email protected]>.
44
//! Email me at <[email protected]>.
5-
//! Email me at <hello@localhost> (this warns but will still become a link).
5+
//! Email me at <hello@localhost>.
6+
//! Email me at <prim@i32>.
67
// @has email_address/index.html '//a[@href="mailto:[email protected]"]' '[email protected]'
78
// @has email_address/index.html '//a[@href="mailto:[email protected]"]' '[email protected]'
89
// @has email_address/index.html '//a[@href="mailto:hello@localhost"]' 'hello@localhost'
10+
// @has email_address/index.html '//a[@href="mailto:prim@i32"]' 'prim@i32'

src/test/ui/borrowck/issue-71546.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Regression test for #71546.
2+
3+
// ignore-compare-mode-nll
4+
// NLL stderr is different from the original one.
5+
6+
pub fn serialize_as_csv<V>(value: &V) -> Result<String, &str>
7+
where
8+
V: 'static,
9+
for<'a> &'a V: IntoIterator,
10+
for<'a> <&'a V as IntoIterator>::Item: ToString + 'static,
11+
{
12+
let csv_str: String = value //~ ERROR: the associated type `<&'a V as IntoIterator>::Item` may not live long enough
13+
.into_iter()
14+
.map(|elem| elem.to_string())
15+
.collect::<String>();
16+
Ok(csv_str)
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)