Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 10 pull requests #91627

Merged
merged 26 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9e5939a
Remove a code path that is neither documented nor can I see the reaso…
oli-obk Aug 20, 2021
93564c3
Tweak "call this function" suggestion to have smaller span
estebank Dec 3, 2021
14c6193
Add test for evaluate_obligation: Ok(EvaluatedToOkModuloRegions) ICE
wesleywiser Nov 19, 2021
98e9b32
Add test with `#[rustc_evaluate_where_clauses]`
wesleywiser Nov 22, 2021
6fe13f6
Add test case that evals to `EvaluatedToOkModuloRegions`
wesleywiser Dec 4, 2021
aa3370c
doc: suggest try_reserve in try_reserve_exact
TennyZhuang Dec 5, 2021
a9f14c1
Add pretty printer test for async blocks
dtolnay Dec 5, 2021
33c29a3
Pretty print async block without redundant space
dtolnay Dec 5, 2021
a30f963
Add `array::IntoIter::{empty, from_raw_parts}`
scottmcm Nov 28, 2021
ef7c833
Move the doc test to edition2021
scottmcm Nov 29, 2021
0b90204
Add tracking issue; make `empty` const too (unstably)
scottmcm Dec 6, 2021
a0fb992
Fix AnonConst ICE
terrarier2111 Nov 28, 2021
6a17ee6
Recommend fix `count()` -> `len()` on slices
notriddle Jul 30, 2021
880eb59
Update books
ehuss Dec 7, 2021
f50070b
:arrow_up: rust-analyzer
lnicola Dec 7, 2021
9b86c59
s/from_raw_parts/new_unchecked/
scottmcm Dec 7, 2021
f84a734
Rollup merge of #87614 - notriddle:notriddle-count2len, r=Mark-Simula…
matthiaskrgr Dec 7, 2021
42d0f83
Rollup merge of #91065 - wesleywiser:add_incr_test, r=jackh726
matthiaskrgr Dec 7, 2021
57ae43d
Rollup merge of #91312 - terrarier2111:anon-const-ice, r=jackh726
matthiaskrgr Dec 7, 2021
677f878
Rollup merge of #91341 - scottmcm:array-iter-frp, r=kennytm
matthiaskrgr Dec 7, 2021
dd929ae
Rollup merge of #91493 - oli-obk:cleanup, r=michaelwoerister
matthiaskrgr Dec 7, 2021
a8f47dc
Rollup merge of #91503 - estebank:call-fn-span, r=michaelwoerister
matthiaskrgr Dec 7, 2021
1c2fba6
Rollup merge of #91547 - TennyZhuang:suggest_try_reserve, r=scottmcm
matthiaskrgr Dec 7, 2021
b2dcfdd
Rollup merge of #91562 - dtolnay:asyncspace, r=Mark-Simulacrum
matthiaskrgr Dec 7, 2021
a3a1402
Rollup merge of #91620 - ehuss:update-books, r=ehuss
matthiaskrgr Dec 7, 2021
099412e
Rollup merge of #91622 - lnicola:rust-analyzer-2021-12-07, r=lnicola
matthiaskrgr Dec 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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