Skip to content

Commit

Permalink
Auto merge of rust-lang#97622 - JohnTitor:rollup-4qoxrjn, r=JohnTitor
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#94647 (Expose `get_many_mut` and `get_many_unchecked_mut` to HashMap)
 - rust-lang#97216 (Ensure we never consider the null pointer dereferencable)
 - rust-lang#97399 (simplify code of finding arg index in `opt_const_param_of`)
 - rust-lang#97470 (rustdoc: add more test coverage)
 - rust-lang#97498 (Corrected EBNF grammar for from_str)
 - rust-lang#97562 (Fix comment in `poly_project_and_unify_type`)
 - rust-lang#97580 (Add regression test for rust-lang#71546)
 - rust-lang#97611 (Tweak insert docs)
 - rust-lang#97616 (Remove an unnecessary `Option`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jun 1, 2022
2 parents 395a09c + 85fdef0 commit 8256e97
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 59 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
msg,
})
}
// Ensure we never consider the null pointer dereferencable.
if M::PointerTag::OFFSET_IS_ADDR {
assert_ne!(ptr.addr(), Size::ZERO);
}
// Test align. Check this last; if both bounds and alignment are violated
// we want the error to be about the bounds.
if let Some(align) = align {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_data_structures/src/sso/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ impl<T: Eq + Hash> SsoHashSet<T> {

/// Adds a value to the set.
///
/// If the set did not have this value present, `true` is returned.
/// Returns whether the value was newly inserted. That is:
///
/// If the set did have this value present, `false` is returned.
/// - If the set did not previously contain this value, `true` is returned.
/// - If the set already contained this value, `false` is returned.
#[inline]
pub fn insert(&mut self, elem: T) -> bool {
self.map.insert(elem, ()).is_none()
Expand Down
28 changes: 14 additions & 14 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,28 @@ impl<'tcx> ProjectionCandidateSet<'tcx> {
}
}

/// Takes the place of a
/// States returned from `poly_project_and_unify_type`. Takes the place
/// of the old return type, which was:
/// ```ignore (not-rust)
/// Result<
/// Result<Option<Vec<PredicateObligation<'tcx>>>, InProgress>,
/// MismatchedProjectionTypes<'tcx>,
/// >
/// ```
pub(super) enum ProjectAndUnifyResult<'tcx> {
/// The projection bound holds subject to the given obligations. If the
/// projection cannot be normalized because the required trait bound does
/// not hold, this is returned, with `obligations` being a predicate that
/// cannot be proven.
Holds(Vec<PredicateObligation<'tcx>>),
/// The projection cannot be normalized due to ambiguity. Resolving some
/// inference variables in the projection may fix this.
FailedNormalization,
/// The project cannot be normalized because `poly_project_and_unify_type`
/// is called recursively while normalizing the same projection.
Recursive,
// the projection can be normalized, but is not equal to the expected type.
// Returns the type error that arose from the mismatch.
MismatchedProjectionTypes(MismatchedProjectionTypes<'tcx>),
}

Expand All @@ -163,19 +176,6 @@ pub(super) enum ProjectAndUnifyResult<'tcx> {
/// ```
/// If successful, this may result in additional obligations. Also returns
/// the projection cache key used to track these additional obligations.
///
/// ## Returns
///
/// - `Err(_)`: the projection can be normalized, but is not equal to the
/// expected type.
/// - `Ok(Err(InProgress))`: this is called recursively while normalizing
/// the same projection.
/// - `Ok(Ok(None))`: The projection cannot be normalized due to ambiguity
/// (resolving some inference variables in the projection may fix this).
/// - `Ok(Ok(Some(obligations)))`: The projection bound holds subject to
/// the given obligations. If the projection cannot be normalized because
/// the required trait bound doesn't hold this returned with `obligations`
/// being a predicate that cannot be proven.
#[instrument(level = "debug", skip(selcx))]
pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,17 @@ pub fn trait_obligations<'a, 'tcx>(
body_id: hir::HirId,
trait_ref: &ty::TraitRef<'tcx>,
span: Span,
item: Option<&'tcx hir::Item<'tcx>>,
item: &'tcx hir::Item<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
let mut wf =
WfPredicates { infcx, param_env, body_id, span, out: vec![], recursion_depth: 0, item };
let mut wf = WfPredicates {
infcx,
param_env,
body_id,
span,
out: vec![],
recursion_depth: 0,
item: Some(item),
};
wf.compute_trait_ref(trait_ref, Elaborate::All);
debug!(obligations = ?wf.out);
wf.normalize()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,7 @@ fn check_impl<'tcx>(
fcx.body_id,
&trait_ref,
ast_trait_ref.path.span,
Some(item),
item,
);
debug!(?obligations);
for obligation in obligations {
Expand Down
47 changes: 16 additions & 31 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,38 +161,23 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// We've encountered an `AnonConst` in some path, so we need to
// figure out which generic parameter it corresponds to and return
// the relevant type.
let filtered = path.segments.iter().find_map(|seg| {
seg.args?
.args
let Some((arg_index, segment)) = path.segments.iter().find_map(|seg| {
let args = seg.args?;
args.args
.iter()
.filter(|arg| arg.is_ty_or_const())
.position(|arg| arg.id() == hir_id)
.map(|index| (index, seg)).or_else(|| args.bindings
.iter()
.filter(|arg| arg.is_ty_or_const())
.position(|arg| arg.id() == hir_id)
.map(|index| (index, seg))
});

// FIXME(associated_const_generics): can we blend this with iteration above?
let (arg_index, segment) = match filtered {
None => {
let binding_filtered = path.segments.iter().find_map(|seg| {
seg.args?
.bindings
.iter()
.filter_map(TypeBinding::opt_const)
.position(|ct| ct.hir_id == hir_id)
.map(|idx| (idx, seg))
});
match binding_filtered {
Some(inner) => inner,
None => {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
"no arg matching AnonConst in path",
);
return None;
}
}
}
Some(inner) => inner,
.filter_map(TypeBinding::opt_const)
.position(|ct| ct.hir_id == hir_id)
.map(|idx| (idx, seg)))
}) else {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
"no arg matching AnonConst in path",
);
return None;
};

// Try to use the segment resolution if it is valid, otherwise we
Expand Down
10 changes: 7 additions & 3 deletions library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,10 +770,14 @@ impl<T> BTreeSet<T> {

/// Adds a value to the set.
///
/// If the set did not have an equal element present, `true` is returned.
/// Returns whether the value was newly inserted. That is:
///
/// If the set did have an equal element present, `false` is returned, and
/// the entry is not updated. See the [module-level documentation] for more.
/// - If the set did not previously contain an equal value, `true` is
/// returned.
/// - If the set already contained an equal value, `false` is returned, and
/// the entry is not updated.
///
/// See the [module-level documentation] for more.
///
/// [module-level documentation]: index.html#insert-and-complex-keys
///
Expand Down
1 change: 0 additions & 1 deletion library/core/src/num/dec2flt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ macro_rules! from_str_float_impl {
/// ```txt
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
/// Number ::= ( Digit+ |
/// '.' Digit* |
/// Digit+ '.' Digit* |
/// Digit* '.' Digit+ ) Exp?
/// Exp ::= 'e' Sign? Digit+
Expand Down
113 changes: 113 additions & 0 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,119 @@ where
self.base.get_key_value(k)
}

/// Attempts to get mutable references to `N` values in the map at once.
///
/// Returns an array of length `N` with the results of each query. For soundness, at most one
/// mutable reference will be returned to any value. `None` will be returned if any of the
/// keys are duplicates or missing.
///
/// # Examples
///
/// ```
/// #![feature(map_many_mut)]
/// use std::collections::HashMap;
///
/// let mut libraries = HashMap::new();
/// libraries.insert("Bodleian Library".to_string(), 1602);
/// libraries.insert("Athenæum".to_string(), 1807);
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
/// libraries.insert("Library of Congress".to_string(), 1800);
///
/// let got = libraries.get_many_mut([
/// "Athenæum",
/// "Library of Congress",
/// ]);
/// assert_eq!(
/// got,
/// Some([
/// &mut 1807,
/// &mut 1800,
/// ]),
/// );
///
/// // Missing keys result in None
/// let got = libraries.get_many_mut([
/// "Athenæum",
/// "New York Public Library",
/// ]);
/// assert_eq!(got, None);
///
/// // Duplicate keys result in None
/// let got = libraries.get_many_mut([
/// "Athenæum",
/// "Athenæum",
/// ]);
/// assert_eq!(got, None);
/// ```
#[inline]
#[unstable(feature = "map_many_mut", issue = "97601")]
pub fn get_many_mut<Q: ?Sized, const N: usize>(&mut self, ks: [&Q; N]) -> Option<[&'_ mut V; N]>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.base.get_many_mut(ks)
}

/// Attempts to get mutable references to `N` values in the map at once, without validating that
/// the values are unique.
///
/// Returns an array of length `N` with the results of each query. `None` will be returned if
/// any of the keys are missing.
///
/// For a safe alternative see [`get_many_mut`](Self::get_many_mut).
///
/// # Safety
///
/// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
/// references are not used.
///
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
///
/// ```
/// #![feature(map_many_mut)]
/// use std::collections::HashMap;
///
/// let mut libraries = HashMap::new();
/// libraries.insert("Bodleian Library".to_string(), 1602);
/// libraries.insert("Athenæum".to_string(), 1807);
/// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
/// libraries.insert("Library of Congress".to_string(), 1800);
///
/// let got = libraries.get_many_mut([
/// "Athenæum",
/// "Library of Congress",
/// ]);
/// assert_eq!(
/// got,
/// Some([
/// &mut 1807,
/// &mut 1800,
/// ]),
/// );
///
/// // Missing keys result in None
/// let got = libraries.get_many_mut([
/// "Athenæum",
/// "New York Public Library",
/// ]);
/// assert_eq!(got, None);
/// ```
#[inline]
#[unstable(feature = "map_many_mut", issue = "97601")]
pub unsafe fn get_many_unchecked_mut<Q: ?Sized, const N: usize>(
&mut self,
ks: [&Q; N],
) -> Option<[&'_ mut V; N]>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.base.get_many_unchecked_mut(ks)
}

/// Returns `true` if the map contains a value for the specified key.
///
/// The key may be any borrowed form of the map's key type, but
Expand Down
5 changes: 3 additions & 2 deletions library/std/src/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,9 +858,10 @@ where

/// Adds a value to the set.
///
/// If the set did not have this value present, `true` is returned.
/// Returns whether the value was newly inserted. That is:
///
/// If the set did have this value present, `false` is returned.
/// - If the set did not previously contain this value, `true` is returned.
/// - If the set already contained this value, `false` is returned.
///
/// # Examples
///
Expand Down
18 changes: 18 additions & 0 deletions src/test/rustdoc/inline_cross/auxiliary/implementors_inline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pub mod my_trait {
pub trait MyTrait {
fn my_fn(&self) -> Self;
}
}

pub mod prelude {
#[doc(inline)]
pub use crate::my_trait::MyTrait;
}

pub struct SomeStruct;

impl my_trait::MyTrait for SomeStruct {
fn my_fn(&self) -> SomeStruct {
SomeStruct
}
}
25 changes: 25 additions & 0 deletions src/test/rustdoc/inline_cross/implementors-js.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// aux-build:implementors_inline.rs
// build-aux-docs
// ignore-cross-compile

extern crate implementors_inline;

// @!has implementors/implementors_js/trait.MyTrait.js
// @has implementors/implementors_inline/my_trait/trait.MyTrait.js
// @!has implementors/implementors_inline/prelude/trait.MyTrait.js
// @has implementors_inline/my_trait/trait.MyTrait.html
// @has - '//script/@src' '../../implementors/implementors_inline/my_trait/trait.MyTrait.js'
// @has implementors_js/trait.MyTrait.html
// @has - '//script/@src' '../implementors/implementors_inline/my_trait/trait.MyTrait.js'
/// When re-exporting this trait, the HTML will be inlined,
/// but, vitally, the JavaScript will be located only at the
/// one canonical path.
pub use implementors_inline::prelude::MyTrait;

pub struct OtherStruct;

impl MyTrait for OtherStruct {
fn my_fn(&self) -> OtherStruct {
OtherStruct
}
}
6 changes: 4 additions & 2 deletions src/test/rustdoc/intra-doc/email-address.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#![allow(rustdoc::broken_intra_doc_links)]
#![forbid(rustdoc::broken_intra_doc_links)]

//! Email me at <hello@example.com>.
//! Email me at <hello-world@example.com>.
//! Email me at <hello@localhost> (this warns but will still become a link).
//! Email me at <hello@localhost>.
//! Email me at <prim@i32>.
// @has email_address/index.html '//a[@href="mailto:hello@example.com"]' 'hello@example.com'
// @has email_address/index.html '//a[@href="mailto:hello-world@example.com"]' 'hello-world@example.com'
// @has email_address/index.html '//a[@href="mailto:hello@localhost"]' 'hello@localhost'
// @has email_address/index.html '//a[@href="mailto:prim@i32"]' 'prim@i32'
19 changes: 19 additions & 0 deletions src/test/ui/borrowck/issue-71546.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Regression test for #71546.

// ignore-compare-mode-nll
// NLL stderr is different from the original one.

pub fn serialize_as_csv<V>(value: &V) -> Result<String, &str>
where
V: 'static,
for<'a> &'a V: IntoIterator,
for<'a> <&'a V as IntoIterator>::Item: ToString + 'static,
{
let csv_str: String = value //~ ERROR: the associated type `<&'a V as IntoIterator>::Item` may not live long enough
.into_iter()
.map(|elem| elem.to_string())
.collect::<String>();
Ok(csv_str)
}

fn main() {}
Loading

0 comments on commit 8256e97

Please sign in to comment.