Skip to content

Commit

Permalink
Auto merge of rust-lang#91627 - matthiaskrgr:rollup-z3e2peg, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 10 pull requests

Successful merges:

 - rust-lang#87614 (Recommend fix `count()` -> `len()` on slices)
 - rust-lang#91065 (Add test for evaluate_obligation: Ok(EvaluatedToOkModuloRegions) ICE)
 - rust-lang#91312 (Fix AnonConst ICE)
 - rust-lang#91341 (Add `array::IntoIter::{empty, from_raw_parts}`)
 - rust-lang#91493 (Remove a dead code path.)
 - rust-lang#91503 (Tweak "call this function" suggestion to have smaller span)
 - rust-lang#91547 (Suggest try_reserve in try_reserve_exact)
 - rust-lang#91562 (Pretty print async block without redundant space)
 - rust-lang#91620 (Update books)
 - rust-lang#91622 (:arrow_up: rust-analyzer)

Failed merges:

 - rust-lang#91571 (Remove unneeded access to pretty printer's `s` field in favor of deref)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 7, 2021
2 parents c67497a + 099412e commit c5c9494
Show file tree
Hide file tree
Showing 31 changed files with 606 additions and 52 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,6 @@ impl<'a> State<'a> {
ast::ExprKind::Async(capture_clause, _, ref blk) => {
self.word_nbsp("async");
self.print_capture_clause(capture_clause);
self.s.space();
// cbox/ibox in analogy to the `ExprKind::Block` arm above
self.cbox(INDENT_UNIT);
self.ibox(0);
Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,6 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
if let Some(def_id) = def_id.as_local() {
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let parent_def_id = self.infcx.defining_use_anchor;
let def_scope_default = || {
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
};
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
{
// Anonymous `impl Trait`
Expand All @@ -481,7 +477,14 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
}) => {
(may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin)
}
_ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
ref itemkind => {
span_bug!(
self.value_span,
"weird opaque type: {:#?}, {:#?}",
ty.kind(),
itemkind
)
}
};
if in_definition_scope {
let opaque_type_key =
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ symbols! {
core_panic_macro,
cosf32,
cosf64,
count,
cr,
crate_id,
crate_in_paths,
Expand Down
26 changes: 23 additions & 3 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
}

pub fn report_method_error(
&self,
mut span: Span,
Expand Down Expand Up @@ -691,7 +695,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let mut restrict_type_params = false;
let mut unsatisfied_bounds = false;
if !unsatisfied_predicates.is_empty() {
if item_name.name == sym::count && self.is_slice_ty(actual, span) {
let msg = "consider using `len` instead";
if let SelfSource::MethodCall(_expr) = source {
err.span_suggestion_short(
span,
msg,
String::from("len"),
Applicability::MachineApplicable,
);
} else {
err.span_label(span, msg);
}
if let Some(iterator_trait) = self.tcx.get_diagnostic_item(sym::Iterator) {
let iterator_trait = self.tcx.def_path_str(iterator_trait);
err.note(&format!("`count` is defined on `{iterator_trait}`, which `{actual}` does not implement"));
}
} else if !unsatisfied_predicates.is_empty() {
let def_span = |def_id| {
self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id))
};
Expand Down Expand Up @@ -990,9 +1010,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

let mut fallback_span = true;
let msg = "remove this method call";
if item_name.name == sym::as_str && actual.peel_refs().is_str() {
let msg = "remove this method call";
let mut fallback_span = true;
if let SelfSource::MethodCall(expr) = source {
let call_expr =
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
Expand Down
25 changes: 11 additions & 14 deletions compiler/rustc_typeck/src/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> bool /* did we suggest to call a function because of missing parentheses? */ {
err.span_label(span, ty.to_string());
if let FnDef(def_id, _) = *ty.kind() {
let source_map = self.tcx.sess.source_map();
if !self.tcx.has_typeck_results(def_id) {
return false;
}
Expand All @@ -517,20 +516,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign))
.is_ok()
{
if let Ok(snippet) = source_map.span_to_snippet(span) {
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
(format!("{}( /* arguments */ )", snippet), Applicability::HasPlaceholders)
} else {
(format!("{}()", snippet), Applicability::MaybeIncorrect)
};
let (variable_snippet, applicability) = if !fn_sig.inputs().is_empty() {
("( /* arguments */ )".to_string(), Applicability::HasPlaceholders)
} else {
("()".to_string(), Applicability::MaybeIncorrect)
};

err.span_suggestion(
span,
"you might have forgotten to call this function",
variable_snippet,
applicability,
);
}
err.span_suggestion_verbose(
span.shrink_to_hi(),
"you might have forgotten to call this function",
variable_snippet,
applicability,
);
return true;
}
}
Expand Down
15 changes: 11 additions & 4 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ 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 (arg_index, segment) = path
let filtered = path
.segments
.iter()
.filter_map(|seg| seg.args.map(|args| (args.args, seg)))
Expand All @@ -181,10 +181,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
.filter(|arg| arg.is_const())
.position(|arg| arg.id() == hir_id)
.map(|index| (index, seg))
})
.unwrap_or_else(|| {
bug!("no arg matching AnonConst in path");
});
let (arg_index, segment) = match filtered {
None => {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
"no arg matching AnonConst in path",
);
return None;
}
Some(inner) => inner,
};

// Try to use the segment resolution if it is valid, otherwise we
// default to the path resolution.
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,9 +720,9 @@ impl<T, A: Allocator> VecDeque<T, A> {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: VecDeque::reserve
/// [`try_reserve`]: VecDeque::try_reserve
///
/// # Errors
///
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1044,9 +1044,9 @@ impl String {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: String::reserve
/// [`try_reserve`]: String::try_reserve
///
/// # Errors
///
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,9 @@ impl<T, A: Allocator> Vec<T, A> {
///
/// Note that the allocator may give the collection more space than it
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`reserve`] if future insertions are expected.
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`reserve`]: Vec::reserve
/// [`try_reserve`]: Vec::try_reserve
///
/// # Errors
///
Expand Down
129 changes: 129 additions & 0 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,135 @@ impl<T, const N: usize> IntoIter<T, N> {
IntoIterator::into_iter(array)
}

/// Creates an iterator over the elements in a partially-initialized buffer.
///
/// If you have a fully-initialized array, then use [`IntoIterator`].
/// But this is useful for returning partial results from unsafe code.
///
/// # Safety
///
/// - The `buffer[initialized]` elements must all be initialized.
/// - The range must be canonical, with `initialized.start <= initialized.end`.
/// - The range must in in-bounds for the buffer, with `initialized.end <= N`.
/// (Like how indexing `[0][100..100]` fails despite the range being empty.)
///
/// It's sound to have more elements initialized than mentioned, though that
/// will most likely result in them being leaked.
///
/// # Examples
///
/// ```
/// #![feature(array_into_iter_constructors)]
///
/// #![feature(maybe_uninit_array_assume_init)]
/// #![feature(maybe_uninit_uninit_array)]
/// use std::array::IntoIter;
/// use std::mem::MaybeUninit;
///
/// # // Hi! Thanks for reading the code. This is restricted to `Copy` because
/// # // otherwise it could leak. A fully-general version this would need a drop
/// # // guard to handle panics from the iterator, but this works for an example.
/// fn next_chunk<T: Copy, const N: usize>(
/// it: &mut impl Iterator<Item = T>,
/// ) -> Result<[T; N], IntoIter<T, N>> {
/// let mut buffer = MaybeUninit::uninit_array();
/// let mut i = 0;
/// while i < N {
/// match it.next() {
/// Some(x) => {
/// buffer[i].write(x);
/// i += 1;
/// }
/// None => {
/// // SAFETY: We've initialized the first `i` items
/// unsafe {
/// return Err(IntoIter::new_unchecked(buffer, 0..i));
/// }
/// }
/// }
/// }
///
/// // SAFETY: We've initialized all N items
/// unsafe { Ok(MaybeUninit::array_assume_init(buffer)) }
/// }
///
/// let r: [_; 4] = next_chunk(&mut (10..16)).unwrap();
/// assert_eq!(r, [10, 11, 12, 13]);
/// let r: IntoIter<_, 40> = next_chunk(&mut (10..16)).unwrap_err();
/// assert_eq!(r.collect::<Vec<_>>(), vec![10, 11, 12, 13, 14, 15]);
/// ```
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const unsafe fn new_unchecked(
buffer: [MaybeUninit<T>; N],
initialized: Range<usize>,
) -> Self {
Self { data: buffer, alive: initialized }
}

/// Creates an iterator over `T` which returns no elements.
///
/// If you just need an empty iterator, then use
/// [`iter::empty()`](crate::iter::empty) instead.
/// And if you need an empty array, use `[]`.
///
/// But this is useful when you need an `array::IntoIter<T, N>` *specifically*.
///
/// # Examples
///
/// ```
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// let empty = IntoIter::<i32, 3>::empty();
/// assert_eq!(empty.len(), 0);
/// assert_eq!(empty.as_slice(), &[]);
///
/// let empty = IntoIter::<std::convert::Infallible, 200>::empty();
/// assert_eq!(empty.len(), 0);
/// ```
///
/// `[1, 2].into_iter()` and `[].into_iter()` have different types
/// ```should_fail,edition2021
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// pub fn get_bytes(b: bool) -> IntoIter<i8, 4> {
/// if b {
/// [1, 2, 3, 4].into_iter()
/// } else {
/// [].into_iter() // error[E0308]: mismatched types
/// }
/// }
/// ```
///
/// But using this method you can get an empty iterator of appropriate size:
/// ```edition2021
/// #![feature(array_into_iter_constructors)]
/// use std::array::IntoIter;
///
/// pub fn get_bytes(b: bool) -> IntoIter<i8, 4> {
/// if b {
/// [1, 2, 3, 4].into_iter()
/// } else {
/// IntoIter::empty()
/// }
/// }
///
/// assert_eq!(get_bytes(true).collect::<Vec<_>>(), vec![1, 2, 3, 4]);
/// assert_eq!(get_bytes(false).collect::<Vec<_>>(), vec![]);
/// ```
#[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const fn empty() -> Self {
let buffer = MaybeUninit::uninit_array();
let initialized = 0..0;

// SAFETY: We're telling it that none of the elements are initialized,
// which is trivially true. And ∀N: usize, 0 <= N.
unsafe { Self::new_unchecked(buffer, initialized) }
}

/// Returns an immutable slice of all elements that have not been yielded
/// yet.
#[stable(feature = "array_value_iter", since = "1.51.0")]
Expand Down
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
#![feature(const_align_of_val)]
#![feature(const_alloc_layout)]
#![feature(const_arguments_as_str)]
#![feature(const_array_into_iter_constructors)]
#![feature(const_bigint_helper_methods)]
#![feature(const_caller_location)]
#![feature(const_cell_into_inner)]
Expand Down Expand Up @@ -138,6 +139,7 @@
#![feature(const_type_name)]
#![feature(const_default_impls)]
#![feature(duration_consts_float)]
#![feature(maybe_uninit_uninit_array)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]
Expand Down
2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 34 files
+2 −2 .github/workflows/main.yml
+2 −2 ADMIN_TASKS.md
+1 −1 README.md
+11 −6 listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt
+1 −1 listings/ch04-understanding-ownership/listing-04-06/output.txt
+1 −1 listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt
+4 −4 listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt
+1 −1 listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.lock
+1 −1 listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt
+1 −1 listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock
+3 −2 listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock
+2 −5 listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt
+1 −1 listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt
+1 −2 listings/ch13-functional-features/listing-13-08/output.txt
+2 −2 listings/ch15-smart-pointers/listing-15-03/output.txt
+1 −1 listings/ch15-smart-pointers/listing-15-21/output.txt
+1 −1 listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt
+1 −1 listings/ch16-fearless-concurrency/listing-16-03/output.txt
+1 −0 listings/ch16-fearless-concurrency/listing-16-14/output.txt
+3 −5 listings/ch18-patterns-and-matching/listing-18-10/output.txt
+5 −3 listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt
+1 −1 listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt
+1,498 −0 nostarch/chapter11.md
+1 −1 rust-toolchain
+1 −1 src/ch00-00-introduction.md
+3 −2 src/ch11-01-writing-tests.md
+1 −1 src/title-page.md
2 changes: 1 addition & 1 deletion src/doc/edition-guide
2 changes: 1 addition & 1 deletion src/doc/nomicon
Submodule nomicon updated 1 files
+2 −2 src/drop-flags.md
2 changes: 1 addition & 1 deletion src/doc/reference
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
Loading

0 comments on commit c5c9494

Please sign in to comment.