Skip to content

Rollup of 4 pull requests #74752

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

Closed
wants to merge 10 commits into from
2 changes: 1 addition & 1 deletion src/doc/rustc/src/codegen-options/index.md
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ This option is deprecated and does nothing.
This option lets you choose which code model to use. \
Code models put constraints on address ranges that the program and its symbols may use. \
With smaller address ranges machine instructions
may be able to use use more compact addressing modes.
may be able to use more compact addressing modes.

The specific ranges depend on target architectures and addressing modes available to them. \
For x86 more detailed description of its code models can be found in
25 changes: 19 additions & 6 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -2974,8 +2974,15 @@ where
#[inline(never)]
#[cold]
#[track_caller]
fn slice_index_len_fail(index: usize, len: usize) -> ! {
panic!("index {} out of range for slice of length {}", index, len);
fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
panic!("range start index {} out of range for slice of length {}", index, len);
}

#[inline(never)]
#[cold]
#[track_caller]
fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
panic!("range end index {} out of range for slice of length {}", index, len);
}

#[inline(never)]
@@ -3160,7 +3167,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
if self.start > self.end {
slice_index_order_fail(self.start, self.end);
} else if self.end > slice.len() {
slice_index_len_fail(self.end, slice.len());
slice_end_index_len_fail(self.end, slice.len());
}
unsafe { &*self.get_unchecked(slice) }
}
@@ -3170,7 +3177,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
if self.start > self.end {
slice_index_order_fail(self.start, self.end);
} else if self.end > slice.len() {
slice_index_len_fail(self.end, slice.len());
slice_end_index_len_fail(self.end, slice.len());
}
unsafe { &mut *self.get_unchecked_mut(slice) }
}
@@ -3241,12 +3248,18 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {

#[inline]
fn index(self, slice: &[T]) -> &[T] {
(self.start..slice.len()).index(slice)
if self.start > slice.len() {
slice_start_index_len_fail(self.start, slice.len());
}
unsafe { &*self.get_unchecked(slice) }
}

#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
(self.start..slice.len()).index_mut(slice)
if self.start > slice.len() {
slice_start_index_len_fail(self.start, slice.len());
}
unsafe { &mut *self.get_unchecked_mut(slice) }
}
}

2 changes: 1 addition & 1 deletion src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
@@ -1088,7 +1088,7 @@ mod slice_index {

good: data[6..] == [];
bad: data[7..];
message: "but ends at"; // perhaps not ideal
message: "out of range";
}

in mod rangeto_len {
57 changes: 55 additions & 2 deletions src/librustc_parse/parser/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use super::ty::AllowPlus;
use super::{BlockMode, Parser, PathStyle, SemiColonMode, SeqSep, TokenExpectType, TokenType};

use rustc_ast::ast::{self, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Item, Param};
use rustc_ast::ast::{AttrVec, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind};
use rustc_ast::ast::{
self, AngleBracketedArgs, AttrVec, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind,
Item, ItemKind, Mutability, Param, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
};
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Lit, LitKind, TokenKind};
use rustc_ast::util::parser::AssocOp;
@@ -488,6 +490,57 @@ impl<'a> Parser<'a> {
false
}

/// Check if a method call with an intended turbofish has been written without surrounding
/// angle brackets.
pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) {
if token::ModSep == self.token.kind && segment.args.is_none() {
let snapshot = self.clone();
self.bump();
let lo = self.token.span;
match self.parse_angle_args() {
Ok(args) => {
let span = lo.to(self.prev_token.span);
// Detect trailing `>` like in `x.collect::Vec<_>>()`.
let mut trailing_span = self.prev_token.span.shrink_to_hi();
while self.token.kind == token::BinOp(token::Shr)
|| self.token.kind == token::Gt
{
trailing_span = trailing_span.to(self.token.span);
self.bump();
}
if self.token.kind == token::OpenDelim(token::Paren) {
// Recover from bad turbofish: `foo.collect::Vec<_>()`.
let args = AngleBracketedArgs { args, span }.into();
segment.args = args;

self.struct_span_err(
span,
"generic parameters without surrounding angle brackets",
)
.multipart_suggestion(
"surround the type parameters with angle brackets",
vec![
(span.shrink_to_lo(), "<".to_string()),
(trailing_span, ">".to_string()),
],
Applicability::MachineApplicable,
)
.emit();
} else {
// This doesn't look like an invalid turbofish, can't recover parse state.
*self = snapshot;
}
}
Err(mut err) => {
// We could't parse generic parameters, unlikely to be a turbofish. Rely on
// generic parse error instead.
err.cancel();
*self = snapshot;
}
}
}
}

/// Check to see if a pair of chained operators looks like an attempt at chained comparison,
/// e.g. `1 < x <= 3`. If so, suggest either splitting the comparison into two, or
/// parenthesising the leftmost comparison.
3 changes: 2 additions & 1 deletion src/librustc_parse/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -909,8 +909,9 @@ impl<'a> Parser<'a> {
}

let fn_span_lo = self.token.span;
let segment = self.parse_path_segment(PathStyle::Expr)?;
let mut segment = self.parse_path_segment(PathStyle::Expr)?;
self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(token::Paren)]);
self.check_turbofish_missing_angle_brackets(&mut segment);

if self.check(&token::OpenDelim(token::Paren)) {
// Method call `expr.f()`
2 changes: 1 addition & 1 deletion src/librustc_parse/parser/path.rs
Original file line number Diff line number Diff line change
@@ -387,7 +387,7 @@ impl<'a> Parser<'a> {

/// Parses (possibly empty) list of generic arguments / associated item constraints,
/// possibly including trailing comma.
fn parse_angle_args(&mut self) -> PResult<'a, Vec<AngleBracketedArg>> {
pub(super) fn parse_angle_args(&mut self) -> PResult<'a, Vec<AngleBracketedArg>> {
let mut args = Vec::new();
while let Some(arg) = self.parse_angle_arg()? {
args.push(arg);
16 changes: 12 additions & 4 deletions src/librustc_trait_selection/traits/wf.rs
Original file line number Diff line number Diff line change
@@ -300,13 +300,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
trait_ref
.substs
.iter()
.filter(|arg| {
.enumerate()
.filter(|(_, arg)| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
})
.filter(|arg| !arg.has_escaping_bound_vars())
.map(|arg| {
.filter(|(_, arg)| !arg.has_escaping_bound_vars())
.map(|(i, arg)| {
let mut new_cause = cause.clone();
// The first subst is the self ty - use the correct span for it.
if i == 0 {
if let Some(hir::ItemKind::Impl { self_ty, .. }) = item.map(|i| &i.kind) {
new_cause.make_mut().span = self_ty.span;
}
}
traits::Obligation::new(
cause.clone(),
new_cause,
param_env,
ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
)
6 changes: 3 additions & 3 deletions src/test/codegen/issue-69101-bounds-check.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
// CHECK-LABEL: @already_sliced_no_bounds_check
#[no_mangle]
pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK: slice_end_index_len_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..2048], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
@@ -23,7 +23,7 @@ pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK-LABEL: @already_sliced_no_bounds_check_exact
#[no_mangle]
pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK: slice_end_index_len_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..1024], &b[..1024], &mut c[..1024]);
for i in 0..1024 {
@@ -35,7 +35,7 @@ pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK-LABEL: @already_sliced_bounds_check
#[no_mangle]
pub fn already_sliced_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK: slice_end_index_len_fail
// CHECK: panic_bounds_check
let _ = (&a[..1023], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:24
|
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
| ------------- ---- ...because method `eq` references the `Self` type in this parameter
| |
| this trait cannot be made into an object...
LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
| ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
|
= help: consider moving `eq` to another trait

Original file line number Diff line number Diff line change
@@ -52,15 +52,15 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
= help: consider moving `foo` to another trait

error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16
|
LL | trait NonObjectSafe1: Sized {}
| -------------- ----- ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
...
LL | impl Trait for dyn NonObjectSafe1 {}
| ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
| ^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object

error: aborting due to 5 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-21837.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0277]: the trait bound `T: Bound` is not satisfied
--> $DIR/issue-21837.rs:8:9
--> $DIR/issue-21837.rs:8:20
|
LL | pub struct Foo<T: Bound>(T);
| ----- required by this bound in `Foo`
...
LL | impl<T> Trait2 for Foo<T> {}
| ^^^^^^ the trait `Bound` is not implemented for `T`
| ^^^^^^ the trait `Bound` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn main() {
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>();
//~^ ERROR generic parameters without surrounding angle brackets
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>>();
//~^ ERROR generic parameters without surrounding angle brackets
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>();
//~^ ERROR generic parameters without surrounding angle brackets
let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>();
//~^ ERROR generic parameters without surrounding angle brackets
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
error: generic parameters without surrounding angle brackets
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:2:48
|
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>();
| ^^^^^^
|
help: surround the type parameters with angle brackets
|
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
| ^ ^

error: generic parameters without surrounding angle brackets
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:4:48
|
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>>();
| ^^^^^^
|
help: surround the type parameters with angle brackets
|
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
| ^ ^

error: generic parameters without surrounding angle brackets
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:6:48
|
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>();
| ^^^^^^
|
help: surround the type parameters with angle brackets
|
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
| ^ ^

error: generic parameters without surrounding angle brackets
--> $DIR/recover-missing-turbofish-surrounding-angle-braket.rs:8:48
|
LL | let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>();
| ^^^^^^
|
help: surround the type parameters with angle brackets
|
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>();
| ^ ^

error: aborting due to 4 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/unsized/unsized-trait-impl-self-type.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0277]: the size for values of type `X` cannot be known at compilation time
--> $DIR/unsized-trait-impl-self-type.rs:10:17
--> $DIR/unsized-trait-impl-self-type.rs:10:27
|
LL | struct S5<Y>(Y);
| - required by this bound in `S5`
LL |
LL | impl<X: ?Sized> T3<X> for S5<X> {
| - ^^^^^ doesn't have a size known at compile-time
| - ^^^^^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `std::marker::Sized`
|
7 changes: 7 additions & 0 deletions src/test/ui/wf/wf-impl-self-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Tests that we point at the proper location for an error
// involving the self-type of an impl

trait Foo {}
impl Foo for Option<[u8]> {} //~ ERROR the size for

fn main() {}
16 changes: 16 additions & 0 deletions src/test/ui/wf/wf-impl-self-type.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/wf-impl-self-type.rs:5:14
|
LL | impl Foo for Option<[u8]> {}
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
::: $SRC_DIR/libcore/option.rs:LL:COL
|
LL | pub enum Option<T> {
| - required by this bound in `std::option::Option`
|
= help: the trait `std::marker::Sized` is not implemented for `[u8]`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.