Skip to content

Commit 3c72788

Browse files
committed
Auto merge of #101479 - Dylan-DPC:rollup-v8ite0y, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #100658 (TyCtxt::get_attr should check that no duplicates are allowed) - #101021 (Migrate ``rustc_middle`` diagnostic) - #101287 (Document eager evaluation of `bool::then_some` argument) - #101412 (Some more cleanup in `core`) - #101427 (Fix ICE, generalize 'move generics to trait' suggestion for >0 non-rcvr arguments) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents a594044 + 8936211 commit 3c72788

File tree

21 files changed

+245
-58
lines changed

21 files changed

+245
-58
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ pub fn from_fn_attrs<'ll, 'tcx>(
386386
) {
387387
let span = cx
388388
.tcx
389-
.get_attr(instance.def_id(), sym::target_feature)
389+
.get_attrs(instance.def_id(), sym::target_feature)
390+
.next()
390391
.map_or_else(|| cx.tcx.def_span(instance.def_id()), |a| a.span);
391392
let msg = format!(
392393
"the target features {} must all be either enabled or disabled together",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
middle_drop_check_overflow =
2+
overflow while adding drop-check rules for {$ty}
3+
.note = overflowed on {$overflow_ty}
4+
5+
middle_opaque_hidden_type_mismatch =
6+
concrete type differs from previous defining opaque type use
7+
.label = expected `{$self_ty}`, got `{$other_ty}`
8+
9+
middle_conflict_types =
10+
this expression supplies two conflicting concrete types for the same opaque type
11+
12+
middle_previous_use_here =
13+
previous use here
14+
15+
middle_limit_invalid =
16+
`limit` must be a non-negative integer
17+
.label = {$error_str}

compiler/rustc_error_messages/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ fluent_messages! {
4747
interface => "../locales/en-US/interface.ftl",
4848
infer => "../locales/en-US/infer.ftl",
4949
lint => "../locales/en-US/lint.ftl",
50+
middle => "../locales/en-US/middle.ftl",
5051
monomorphize => "../locales/en-US/monomorphize.ftl",
5152
metadata => "../locales/en-US/metadata.ftl",
5253
parser => "../locales/en-US/parser.ftl",

compiler/rustc_feature/src/builtin_attrs.rs

+8
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,14 @@ pub fn is_builtin_only_local(name: Symbol) -> bool {
823823
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| attr.only_local)
824824
}
825825

826+
pub fn is_valid_for_get_attr(name: Symbol) -> bool {
827+
BUILTIN_ATTRIBUTE_MAP.get(&name).map_or(false, |attr| match attr.duplicates {
828+
WarnFollowing | ErrorFollowing | ErrorPreceding | FutureWarnFollowing
829+
| FutureWarnPreceding => true,
830+
DuplicatesOk | WarnFollowingWordOnly => false,
831+
})
832+
}
833+
826834
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock<FxHashMap<Symbol, &BuiltinAttribute>> =
827835
LazyLock::new(|| {
828836
let mut map = FxHashMap::default();

compiler/rustc_feature/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
151151
pub use builtin_attrs::AttributeDuplicates;
152152
pub use builtin_attrs::{
153153
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
154-
AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg,
155-
BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
154+
is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
155+
GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
156156
};
157157
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};

compiler/rustc_middle/src/error.rs

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use rustc_macros::SessionDiagnostic;
2+
use rustc_span::Span;
3+
4+
use crate::ty::Ty;
5+
6+
#[derive(SessionDiagnostic)]
7+
#[diag(middle::drop_check_overflow, code = "E0320")]
8+
#[note]
9+
pub struct DropCheckOverflow<'tcx> {
10+
#[primary_span]
11+
pub span: Span,
12+
pub ty: Ty<'tcx>,
13+
pub overflow_ty: Ty<'tcx>,
14+
}
15+
16+
#[derive(SessionDiagnostic)]
17+
#[diag(middle::opaque_hidden_type_mismatch)]
18+
pub struct OpaqueHiddenTypeMismatch<'tcx> {
19+
pub self_ty: Ty<'tcx>,
20+
pub other_ty: Ty<'tcx>,
21+
#[primary_span]
22+
#[label]
23+
pub other_span: Span,
24+
#[subdiagnostic]
25+
pub sub: TypeMismatchReason,
26+
}
27+
28+
#[derive(SessionSubdiagnostic)]
29+
pub enum TypeMismatchReason {
30+
#[label(middle::conflict_types)]
31+
ConflictType {
32+
#[primary_span]
33+
span: Span,
34+
},
35+
#[note(middle::previous_use_here)]
36+
PreviousUse {
37+
#[primary_span]
38+
span: Span,
39+
},
40+
}
41+
42+
#[derive(SessionDiagnostic)]
43+
#[diag(middle::limit_invalid)]
44+
pub struct LimitInvalid<'a> {
45+
#[primary_span]
46+
pub span: Span,
47+
#[label]
48+
pub value_span: Span,
49+
pub error_str: &'a str,
50+
}

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ pub mod query;
8686
pub mod arena;
8787
#[macro_use]
8888
pub mod dep_graph;
89+
pub(crate) mod error;
8990
pub mod hir;
9091
pub mod infer;
9192
pub mod lint;

compiler/rustc_middle/src/middle/limits.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//! just peeks and looks for that attribute.
1111
1212
use crate::bug;
13+
use crate::error::LimitInvalid;
1314
use crate::ty;
1415
use rustc_ast::Attribute;
1516
use rustc_session::Session;
@@ -56,9 +57,6 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u
5657
match s.as_str().parse() {
5758
Ok(n) => return Limit::new(n),
5859
Err(e) => {
59-
let mut err =
60-
sess.struct_span_err(attr.span, "`limit` must be a non-negative integer");
61-
6260
let value_span = attr
6361
.meta()
6462
.and_then(|meta| meta.name_value_literal_span())
@@ -74,9 +72,7 @@ fn get_limit(krate_attrs: &[Attribute], sess: &Session, name: Symbol, default: u
7472
IntErrorKind::Zero => bug!("zero is a valid `limit`"),
7573
kind => bug!("unimplemented IntErrorKind variant: {:?}", kind),
7674
};
77-
78-
err.span_label(value_span, error_str);
79-
err.emit();
75+
sess.emit_err(LimitInvalid { span: attr.span, value_span, error_str });
8076
}
8177
}
8278
}

compiler/rustc_middle/src/traits/query.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
//! The providers for the queries defined here can be found in
66
//! `rustc_traits`.
77
8+
use crate::error::DropCheckOverflow;
89
use crate::infer::canonical::{Canonical, QueryResponse};
910
use crate::ty::error::TypeError;
1011
use crate::ty::subst::GenericArg;
1112
use crate::ty::{self, Ty, TyCtxt};
12-
use rustc_errors::struct_span_err;
1313
use rustc_span::source_map::Span;
1414
use std::iter::FromIterator;
1515

@@ -117,15 +117,7 @@ pub struct DropckOutlivesResult<'tcx> {
117117
impl<'tcx> DropckOutlivesResult<'tcx> {
118118
pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
119119
if let Some(overflow_ty) = self.overflows.get(0) {
120-
let mut err = struct_span_err!(
121-
tcx.sess,
122-
span,
123-
E0320,
124-
"overflow while adding drop-check rules for {}",
125-
ty,
126-
);
127-
err.note(&format!("overflowed on {}", overflow_ty));
128-
err.emit();
120+
tcx.sess.emit_err(DropCheckOverflow { span, ty, overflow_ty: *overflow_ty });
129121
}
130122
}
131123

compiler/rustc_middle/src/ty/mod.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub use self::AssocItemContainer::*;
1515
pub use self::BorrowKind::*;
1616
pub use self::IntVarValue::*;
1717
pub use self::Variance::*;
18+
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
1819
use crate::metadata::ModChild;
1920
use crate::middle::privacy::AccessLevels;
2021
use crate::mir::{Body, GeneratorLayout};
@@ -1179,20 +1180,17 @@ pub struct OpaqueHiddenType<'tcx> {
11791180
impl<'tcx> OpaqueHiddenType<'tcx> {
11801181
pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
11811182
// Found different concrete types for the opaque type.
1182-
let mut err = tcx.sess.struct_span_err(
1183-
other.span,
1184-
"concrete type differs from previous defining opaque type use",
1185-
);
1186-
err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty));
1187-
if self.span == other.span {
1188-
err.span_label(
1189-
self.span,
1190-
"this expression supplies two conflicting concrete types for the same opaque type",
1191-
);
1183+
let sub_diag = if self.span == other.span {
1184+
TypeMismatchReason::ConflictType { span: self.span }
11921185
} else {
1193-
err.span_note(self.span, "previous use here");
1194-
}
1195-
err.emit();
1186+
TypeMismatchReason::PreviousUse { span: self.span }
1187+
};
1188+
tcx.sess.emit_err(OpaqueHiddenTypeMismatch {
1189+
self_ty: self.ty,
1190+
other_ty: other.ty,
1191+
other_span: other.span,
1192+
sub: sub_diag,
1193+
});
11961194
}
11971195
}
11981196

@@ -2269,7 +2267,11 @@ impl<'tcx> TyCtxt<'tcx> {
22692267
}
22702268

22712269
pub fn get_attr(self, did: DefId, attr: Symbol) -> Option<&'tcx ast::Attribute> {
2272-
self.get_attrs(did, attr).next()
2270+
if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
2271+
bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
2272+
} else {
2273+
self.get_attrs(did, attr).next()
2274+
}
22732275
}
22742276

22752277
/// Determines whether an item is annotated with an attribute.

compiler/rustc_typeck/src/check/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1459,7 +1459,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, vs: &'tcx [hir::Variant<'tcx>], def_id: L
14591459
def.destructor(tcx); // force the destructor to be evaluated
14601460

14611461
if vs.is_empty() {
1462-
if let Some(attr) = tcx.get_attr(def_id.to_def_id(), sym::repr) {
1462+
if let Some(attr) = tcx.get_attrs(def_id.to_def_id(), sym::repr).next() {
14631463
struct_span_err!(
14641464
tcx.sess,
14651465
attr.span,

compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs

+33-11
Original file line numberDiff line numberDiff line change
@@ -749,23 +749,45 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
749749
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
750750
&self,
751751
err: &mut Diagnostic,
752-
trait_: DefId,
752+
trait_def_id: DefId,
753753
expr: &'tcx hir::Expr<'tcx>,
754754
msg: String,
755755
num_assoc_fn_excess_args: usize,
756756
num_trait_generics_except_self: usize,
757757
) {
758-
if let hir::ExprKind::MethodCall(_, receiver, args, ..) = expr.kind {
759-
assert_eq!(args.len(), 0);
760-
if num_assoc_fn_excess_args == num_trait_generics_except_self {
761-
if let Some(gen_args) = self.gen_args.span_ext()
762-
&& let Ok(gen_args) = self.tcx.sess.source_map().span_to_snippet(gen_args)
763-
&& let Ok(receiver) = self.tcx.sess.source_map().span_to_snippet(receiver.span) {
764-
let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), receiver);
765-
err.span_suggestion(expr.span, msg, sugg, Applicability::MaybeIncorrect);
766-
}
767-
}
758+
let sm = self.tcx.sess.source_map();
759+
let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return; };
760+
if num_assoc_fn_excess_args != num_trait_generics_except_self {
761+
return;
768762
}
763+
let Some(gen_args) = self.gen_args.span_ext() else { return; };
764+
let Ok(generics) = sm.span_to_snippet(gen_args) else { return; };
765+
let Ok(rcvr) = sm.span_to_snippet(
766+
rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span)
767+
) else { return; };
768+
let Ok(rest) =
769+
(match args {
770+
[] => Ok(String::new()),
771+
[arg] => sm.span_to_snippet(
772+
arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span),
773+
),
774+
[first, .., last] => {
775+
let first_span =
776+
first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
777+
let last_span =
778+
last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
779+
sm.span_to_snippet(first_span.to(last_span))
780+
}
781+
}) else { return; };
782+
let comma = if args.len() > 0 { ", " } else { "" };
783+
let trait_path = self.tcx.def_path_str(trait_def_id);
784+
let method_name = self.tcx.item_name(self.def_id);
785+
err.span_suggestion(
786+
expr.span,
787+
msg,
788+
format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
789+
Applicability::MaybeIncorrect,
790+
);
769791
}
770792

771793
/// Suggests to remove redundant argument(s):

library/core/src/bool.rs

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ impl bool {
66
/// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
77
/// or `None` otherwise.
88
///
9+
/// Arguments passed to `then_some` are eagerly evaluated; if you are
10+
/// passing the result of a function call, it is recommended to use
11+
/// [`then`], which is lazily evaluated.
12+
///
13+
/// [`then`]: bool::then
14+
///
915
/// # Examples
1016
///
1117
/// ```

library/core/src/slice/iter/macros.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ macro_rules! iterator {
6464
// backwards by `n`. `n` must not exceed `self.len()`.
6565
macro_rules! zst_shrink {
6666
($self: ident, $n: ident) => {
67-
$self.end = $self.end.wrapping_byte_offset(-$n);
67+
$self.end = $self.end.wrapping_byte_sub($n);
6868
}
6969
}
7070

@@ -82,15 +82,15 @@ macro_rules! iterator {
8282
// returning the old start.
8383
// Unsafe because the offset must not exceed `self.len()`.
8484
#[inline(always)]
85-
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
85+
unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T {
8686
if mem::size_of::<T>() == 0 {
8787
zst_shrink!(self, offset);
8888
self.ptr.as_ptr()
8989
} else {
9090
let old = self.ptr.as_ptr();
9191
// SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
9292
// so this new pointer is inside `self` and thus guaranteed to be non-null.
93-
self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().offset(offset)) };
93+
self.ptr = unsafe { NonNull::new_unchecked(self.ptr.as_ptr().add(offset)) };
9494
old
9595
}
9696
}
@@ -99,15 +99,15 @@ macro_rules! iterator {
9999
// returning the new end.
100100
// Unsafe because the offset must not exceed `self.len()`.
101101
#[inline(always)]
102-
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
102+
unsafe fn pre_dec_end(&mut self, offset: usize) -> * $raw_mut T {
103103
if mem::size_of::<T>() == 0 {
104104
zst_shrink!(self, offset);
105105
self.ptr.as_ptr()
106106
} else {
107107
// SAFETY: the caller guarantees that `offset` doesn't exceed `self.len()`,
108108
// which is guaranteed to not overflow an `isize`. Also, the resulting pointer
109109
// is in bounds of `slice`, which fulfills the other requirements for `offset`.
110-
self.end = unsafe { self.end.offset(-offset) };
110+
self.end = unsafe { self.end.sub(offset) };
111111
self.end
112112
}
113113
}
@@ -180,7 +180,7 @@ macro_rules! iterator {
180180
}
181181
// SAFETY: We are in bounds. `post_inc_start` does the right thing even for ZSTs.
182182
unsafe {
183-
self.post_inc_start(n as isize);
183+
self.post_inc_start(n);
184184
Some(next_unchecked!(self))
185185
}
186186
}
@@ -189,7 +189,7 @@ macro_rules! iterator {
189189
fn advance_by(&mut self, n: usize) -> Result<(), usize> {
190190
let advance = cmp::min(len!(self), n);
191191
// SAFETY: By construction, `advance` does not exceed `self.len()`.
192-
unsafe { self.post_inc_start(advance as isize) };
192+
unsafe { self.post_inc_start(advance) };
193193
if advance == n { Ok(()) } else { Err(advance) }
194194
}
195195

@@ -375,7 +375,7 @@ macro_rules! iterator {
375375
}
376376
// SAFETY: We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
377377
unsafe {
378-
self.pre_dec_end(n as isize);
378+
self.pre_dec_end(n);
379379
Some(next_back_unchecked!(self))
380380
}
381381
}
@@ -384,7 +384,7 @@ macro_rules! iterator {
384384
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
385385
let advance = cmp::min(len!(self), n);
386386
// SAFETY: By construction, `advance` does not exceed `self.len()`.
387-
unsafe { self.pre_dec_end(advance as isize) };
387+
unsafe { self.pre_dec_end(advance) };
388388
if advance == n { Ok(()) } else { Err(advance) }
389389
}
390390
}

0 commit comments

Comments
 (0)