Skip to content

Commit c9c4b5d

Browse files
committed
Auto merge of rust-lang#90984 - matthiaskrgr:rollup-j5bs96a, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#89610 (warn on must_use use on async fn's) - rust-lang#90667 (Improve diagnostics when a static lifetime is expected) - rust-lang#90687 (Permit const panics in stable const contexts in stdlib) - rust-lang#90772 (Add Vec::retain_mut) - rust-lang#90861 (Print escaped string if char literal has multiple characters, but only one printable character) - rust-lang#90884 (Fix span for non-satisfied trivial trait bounds) - rust-lang#90900 (Remove workaround for the forward progress handling in LLVM) - rust-lang#90901 (Improve ManuallyDrop suggestion) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents faea820 + 469faa2 commit c9c4b5d

File tree

58 files changed

+648
-357
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+648
-357
lines changed

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
316316
extended_asm.add_input_operand(None, "r", result.llval);
317317
extended_asm.add_clobber("memory");
318318
extended_asm.set_volatile_flag(true);
319-
319+
320320
// We have copied the value to `result` already.
321321
return;
322322
}
@@ -363,10 +363,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
363363
cond
364364
}
365365

366-
fn sideeffect(&mut self) {
367-
// TODO(antoyo)
368-
}
369-
370366
fn type_test(&mut self, _pointer: Self::Value, _typeid: Self::Value) -> Self::Value {
371367
// Unsupported.
372368
self.context.new_rvalue_from_int(self.int_type, 0)

compiler/rustc_codegen_llvm/src/context.rs

-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,6 @@ impl CodegenCx<'b, 'tcx> {
597597
ifn!("llvm.trap", fn() -> void);
598598
ifn!("llvm.debugtrap", fn() -> void);
599599
ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
600-
ifn!("llvm.sideeffect", fn() -> void);
601600

602601
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
603602
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);

compiler/rustc_codegen_llvm/src/intrinsic.rs

-9
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
392392
self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
393393
}
394394

395-
fn sideeffect(&mut self) {
396-
// This kind of check would make a ton of sense in the caller, but currently the only
397-
// caller of this function is in `rustc_codegen_ssa`, which is agnostic to whether LLVM
398-
// codegen backend being used, and so is unable to check the LLVM version.
399-
if unsafe { llvm::LLVMRustVersionMajor() } < 12 {
400-
self.call_intrinsic("llvm.sideeffect", &[]);
401-
}
402-
}
403-
404395
fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value {
405396
// Test the called operand using llvm.type.test intrinsic. The LowerTypeTests link-time
406397
// optimization pass replaces calls to this intrinsic with code to test type membership.

compiler/rustc_codegen_ssa/src/mir/block.rs

-11
Original file line numberDiff line numberDiff line change
@@ -980,17 +980,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
980980
}
981981

982982
mir::TerminatorKind::Goto { target } => {
983-
if bb == target {
984-
// This is an unconditional branch back to this same basic block. That means we
985-
// have something like a `loop {}` statement. LLVM versions before 12.0
986-
// miscompile this because they assume forward progress. For older versions
987-
// try to handle just this specific case which comes up commonly in practice
988-
// (e.g., in embedded code).
989-
//
990-
// NB: the `sideeffect` currently checks for the LLVM version used internally.
991-
bx.sideeffect();
992-
}
993-
994983
helper.funclet_br(self, &mut bx, target);
995984
}
996985

compiler/rustc_codegen_ssa/src/traits/intrinsic.rs

-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
2020
fn abort(&mut self);
2121
fn assume(&mut self, val: Self::Value);
2222
fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value;
23-
/// Emits a forced side effect.
24-
///
25-
/// Currently has any effect only when LLVM versions prior to 12.0 are used as the backend.
26-
fn sideeffect(&mut self);
2723
/// Trait method used to test whether a given pointer is associated with a type identifier.
2824
fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value;
2925
/// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs

+24-41
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
44
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
55
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
6-
use rustc_hir::intravisit::Visitor;
7-
use rustc_hir::FnRetTy;
86
use rustc_middle::ty;
97

108
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -48,19 +46,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
4846
return None; // inapplicable
4947
};
5048

49+
// Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
50+
// and can steer users down the wrong path.
51+
if *named == ty::ReStatic {
52+
return None;
53+
}
54+
5155
debug!("try_report_named_anon_conflict: named = {:?}", named);
5256
debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
5357
debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
5458

55-
let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
56-
anon_param_info.param,
57-
anon_param_info.param_ty,
58-
anon_param_info.param_ty_span,
59-
anon_param_info.bound_region,
60-
anon_param_info.is_first,
61-
region_info.def_id,
62-
region_info.is_impl_item,
63-
);
59+
let param = anon_param_info.param;
60+
let new_ty = anon_param_info.param_ty;
61+
let new_ty_span = anon_param_info.param_ty_span;
62+
let br = anon_param_info.bound_region;
63+
let is_first = anon_param_info.is_first;
64+
let scope_def_id = region_info.def_id;
65+
let is_impl_item = region_info.is_impl_item;
66+
6467
match br {
6568
ty::BrAnon(_) => {}
6669
_ => {
@@ -75,26 +78,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
7578
return None;
7679
}
7780

78-
if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
79-
if self.is_self_anon(is_first, scope_def_id) {
80-
return None;
81-
}
82-
83-
if let FnRetTy::Return(ty) = &fndecl.output {
84-
let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir());
85-
v.visit_ty(ty);
86-
87-
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
88-
if sub == &ty::ReStatic
89-
&& v.0.into_iter().any(|t| t.span.desugaring_kind().is_none())
90-
{
91-
// If the failure is due to a `'static` requirement coming from a `dyn` or
92-
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
93-
// better in `static_impl_trait`.
94-
debug!("try_report_named_anon_conflict: impl Trait + 'static");
95-
return None;
96-
}
97-
}
81+
if find_anon_type(self.tcx(), anon, &br).is_some()
82+
&& self.is_self_anon(is_first, scope_def_id)
83+
{
84+
return None;
9885
}
9986

10087
let (error_var, span_label_var) = match param.pat.simple_ident() {
@@ -114,16 +101,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
114101
);
115102

116103
diag.span_label(span, format!("lifetime `{}` required", named));
117-
// Suggesting `'static` is nearly always incorrect, and can steer users
118-
// down the wrong path.
119-
if *named != ty::ReStatic {
120-
diag.span_suggestion(
121-
new_ty_span,
122-
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
123-
new_ty.to_string(),
124-
Applicability::Unspecified,
125-
);
126-
}
104+
diag.span_suggestion(
105+
new_ty_span,
106+
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
107+
new_ty.to_string(),
108+
Applicability::Unspecified,
109+
);
127110

128111
Some(diag)
129112
}

compiler/rustc_infer/src/traits/util.rs

+17
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
55
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
66
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
77
use rustc_span::symbol::Ident;
8+
use rustc_span::Span;
89

910
pub fn anonymize_predicate<'tcx>(
1011
tcx: TyCtxt<'tcx>,
@@ -97,6 +98,22 @@ pub fn elaborate_predicates<'tcx>(
9798
elaborate_obligations(tcx, obligations)
9899
}
99100

101+
pub fn elaborate_predicates_with_span<'tcx>(
102+
tcx: TyCtxt<'tcx>,
103+
predicates: impl Iterator<Item = (ty::Predicate<'tcx>, Span)>,
104+
) -> Elaborator<'tcx> {
105+
let obligations = predicates
106+
.map(|(predicate, span)| {
107+
predicate_obligation(
108+
predicate,
109+
ty::ParamEnv::empty(),
110+
ObligationCause::dummy_with_span(span),
111+
)
112+
})
113+
.collect();
114+
elaborate_obligations(tcx, obligations)
115+
}
116+
100117
pub fn elaborate_obligations<'tcx>(
101118
tcx: TyCtxt<'tcx>,
102119
mut obligations: Vec<PredicateObligation<'tcx>>,

compiler/rustc_parse/src/lexer/unescape_error_reporting.rs

+27
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,33 @@ pub(crate) fn emit_unescape_error(
8282
Applicability::MachineApplicable,
8383
);
8484
}
85+
} else {
86+
let printable: Vec<char> = lit
87+
.chars()
88+
.filter(|&x| {
89+
unicode_width::UnicodeWidthChar::width(x).unwrap_or(0) != 0
90+
&& !x.is_whitespace()
91+
})
92+
.collect();
93+
94+
if let [ch] = printable.as_slice() {
95+
has_help = true;
96+
97+
handler.span_note(
98+
span,
99+
&format!(
100+
"there are non-printing characters, the full sequence is `{}`",
101+
lit.escape_default(),
102+
),
103+
);
104+
105+
handler.span_suggestion(
106+
span,
107+
"consider removing the non-printing characters",
108+
ch.to_string(),
109+
Applicability::MaybeIncorrect,
110+
);
111+
}
85112
}
86113

87114
if !has_help {

compiler/rustc_passes/src/check_attr.rs

+32
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl CheckAttrVisitor<'tcx> {
112112
self.check_default_method_body_is_const(attr, span, target)
113113
}
114114
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
115+
sym::must_use => self.check_must_use(hir_id, &attr, span, target),
115116
sym::rustc_const_unstable
116117
| sym::rustc_const_stable
117118
| sym::unstable
@@ -1046,6 +1047,37 @@ impl CheckAttrVisitor<'tcx> {
10461047
is_valid
10471048
}
10481049

1050+
/// Warns against some misuses of `#[must_use]`
1051+
fn check_must_use(
1052+
&self,
1053+
hir_id: HirId,
1054+
attr: &Attribute,
1055+
span: &Span,
1056+
_target: Target,
1057+
) -> bool {
1058+
let node = self.tcx.hir().get(hir_id);
1059+
if let Some(fn_node) = node.fn_kind() {
1060+
if let rustc_hir::IsAsync::Async = fn_node.asyncness() {
1061+
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
1062+
lint.build(
1063+
"`must_use` attribute on `async` functions \
1064+
applies to the anonymous `Future` returned by the \
1065+
function, not the value within",
1066+
)
1067+
.span_label(
1068+
*span,
1069+
"this attribute does nothing, the `Future`s \
1070+
returned by async functions are already `must_use`",
1071+
)
1072+
.emit();
1073+
});
1074+
}
1075+
}
1076+
1077+
// For now, its always valid
1078+
true
1079+
}
1080+
10491081
/// Checks if `#[must_not_suspend]` is applied to a function. Returns `true` if valid.
10501082
fn check_must_not_suspend(&self, attr: &Attribute, span: &Span, target: Target) -> bool {
10511083
match target {

compiler/rustc_trait_selection/src/traits/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub use self::specialize::{specialization_graph, translate_substs, OverlapError}
6565
pub use self::structural_match::search_for_structural_match_violation;
6666
pub use self::structural_match::NonStructuralMatchTy;
6767
pub use self::util::{
68-
elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs,
68+
elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span,
69+
elaborate_trait_ref, elaborate_trait_refs,
6970
};
7071
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
7172
pub use self::util::{

compiler/rustc_typeck/src/check/check.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -371,16 +371,26 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
371371
let param_env = tcx.param_env(item_def_id);
372372
for field in fields {
373373
let field_ty = field.ty(tcx, substs);
374-
// We are currently checking the type this field came from, so it must be local.
375-
let field_span = tcx.hir().span_if_local(field.did).unwrap();
376374
if field_ty.needs_drop(tcx, param_env) {
375+
let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
376+
// We are currently checking the type this field came from, so it must be local.
377+
Some(Node::Field(field)) => (field.span, field.ty.span),
378+
_ => unreachable!("mir field has to correspond to hir field"),
379+
};
377380
struct_span_err!(
378381
tcx.sess,
379382
field_span,
380383
E0740,
381384
"unions may not contain fields that need dropping"
382385
)
383-
.span_note(field_span, "`std::mem::ManuallyDrop` can be used to wrap the type")
386+
.multipart_suggestion_verbose(
387+
"wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped",
388+
vec![
389+
(ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
390+
(ty_span.shrink_to_hi(), ">".into()),
391+
],
392+
Applicability::MaybeIncorrect,
393+
)
384394
.emit();
385395
return false;
386396
}

compiler/rustc_typeck/src/check/wfcheck.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1641,19 +1641,38 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) {
16411641

16421642
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
16431643
/// aren't true.
1644-
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
1644+
fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirId) {
16451645
let empty_env = ty::ParamEnv::empty();
16461646

16471647
let def_id = fcx.tcx.hir().local_def_id(id);
1648-
let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p);
1648+
let predicates_with_span =
1649+
fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, span)| (*p, *span));
16491650
// Check elaborated bounds.
1650-
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
1651+
let implied_obligations = traits::elaborate_predicates_with_span(fcx.tcx, predicates_with_span);
16511652

16521653
for obligation in implied_obligations {
16531654
let pred = obligation.predicate;
16541655
// Match the existing behavior.
16551656
if pred.is_global(fcx.tcx) && !pred.has_late_bound_regions() {
16561657
let pred = fcx.normalize_associated_types_in(span, pred);
1658+
let hir_node = fcx.tcx.hir().find(id);
1659+
1660+
// only use the span of the predicate clause (#90869)
1661+
1662+
if let Some(hir::Generics { where_clause, .. }) =
1663+
hir_node.and_then(|node| node.generics())
1664+
{
1665+
let obligation_span = obligation.cause.span(fcx.tcx);
1666+
1667+
span = where_clause
1668+
.predicates
1669+
.iter()
1670+
// There seems to be no better way to find out which predicate we are in
1671+
.find(|pred| pred.span().contains(obligation_span))
1672+
.map(|pred| pred.span())
1673+
.unwrap_or(obligation_span);
1674+
}
1675+
16571676
let obligation = traits::Obligation::new(
16581677
traits::ObligationCause::new(span, id, traits::TrivialBound),
16591678
empty_env,

0 commit comments

Comments
 (0)