Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4459e72

Browse files
committedDec 8, 2021
Auto merge of rust-lang#91656 - matthiaskrgr:rollup-lk96y6d, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - rust-lang#83744 (Deprecate crate_type and crate_name nested inside #![cfg_attr]) - rust-lang#90550 (Update certificates in some Ubuntu 16 images.) - rust-lang#91272 (Print a suggestion when comparing references to primitive types in `const fn`) - rust-lang#91467 (Emphasise that an OsStr[ing] is not necessarily a platform string) - rust-lang#91531 (Do not add `;` to expected tokens list when it's wrong) - rust-lang#91577 (Address some FIXMEs left over from rust-lang#91475) - rust-lang#91638 (Remove `in_band_lifetimes` from `rustc_mir_transform`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ce0f7ba + 90690da commit 4459e72

File tree

70 files changed

+624
-219
lines changed

Some content is hidden

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

70 files changed

+624
-219
lines changed
 

‎compiler/rustc_const_eval/src/transform/check_consts/check.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
801801
if let Some(trait_id) = tcx.trait_of_item(callee) {
802802
trace!("attempting to call a trait method");
803803
if !self.tcx.features().const_trait_impl {
804-
self.check_op(ops::FnCallNonConst);
804+
self.check_op(ops::FnCallNonConst(Some((callee, substs))));
805805
return;
806806
}
807807

@@ -857,7 +857,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
857857
}
858858

859859
if !nonconst_call_permission {
860-
self.check_op(ops::FnCallNonConst);
860+
self.check_op(ops::FnCallNonConst(None));
861861
return;
862862
}
863863
}
@@ -926,7 +926,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
926926
}
927927

928928
if !nonconst_call_permission {
929-
self.check_op(ops::FnCallNonConst);
929+
self.check_op(ops::FnCallNonConst(None));
930930
return;
931931
}
932932
}

‎compiler/rustc_const_eval/src/transform/check_consts/ops.rs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
//! Concrete error types for all operations which may be invalid in a certain const context.
22
3-
use rustc_errors::{struct_span_err, DiagnosticBuilder};
3+
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::DefId;
6-
use rustc_middle::mir;
6+
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
7+
use rustc_middle::{mir, ty::AssocKind};
78
use rustc_session::parse::feature_err;
89
use rustc_span::symbol::sym;
9-
use rustc_span::{Span, Symbol};
10+
use rustc_span::{symbol::Ident, Span, Symbol};
11+
use rustc_span::{BytePos, Pos};
1012

1113
use super::ConstCx;
1214

@@ -72,17 +74,71 @@ impl NonConstOp for FnCallIndirect {
7274

7375
/// A function call where the callee is not marked as `const`.
7476
#[derive(Debug)]
75-
pub struct FnCallNonConst;
76-
impl NonConstOp for FnCallNonConst {
77+
pub struct FnCallNonConst<'tcx>(pub Option<(DefId, SubstsRef<'tcx>)>);
78+
impl<'a> NonConstOp for FnCallNonConst<'a> {
7779
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
78-
struct_span_err!(
80+
let mut err = struct_span_err!(
7981
ccx.tcx.sess,
8082
span,
8183
E0015,
8284
"calls in {}s are limited to constant functions, \
8385
tuple structs and tuple variants",
8486
ccx.const_kind(),
85-
)
87+
);
88+
89+
if let FnCallNonConst(Some((callee, substs))) = *self {
90+
if let Some(trait_def_id) = ccx.tcx.lang_items().eq_trait() {
91+
if let Some(eq_item) = ccx.tcx.associated_items(trait_def_id).find_by_name_and_kind(
92+
ccx.tcx,
93+
Ident::with_dummy_span(sym::eq),
94+
AssocKind::Fn,
95+
trait_def_id,
96+
) {
97+
if callee == eq_item.def_id && substs.len() == 2 {
98+
match (substs[0].unpack(), substs[1].unpack()) {
99+
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
100+
if self_ty == rhs_ty
101+
&& self_ty.is_ref()
102+
&& self_ty.peel_refs().is_primitive() =>
103+
{
104+
let mut num_refs = 0;
105+
let mut tmp_ty = self_ty;
106+
while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() {
107+
num_refs += 1;
108+
tmp_ty = inner_ty;
109+
}
110+
let deref = "*".repeat(num_refs);
111+
112+
if let Ok(call_str) =
113+
ccx.tcx.sess.source_map().span_to_snippet(span)
114+
{
115+
if let Some(eq_idx) = call_str.find("==") {
116+
if let Some(rhs_idx) = call_str[(eq_idx + 2)..]
117+
.find(|c: char| !c.is_whitespace())
118+
{
119+
let rhs_pos = span.lo()
120+
+ BytePos::from_usize(eq_idx + 2 + rhs_idx);
121+
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
122+
err.multipart_suggestion(
123+
"consider dereferencing here",
124+
vec![
125+
(span.shrink_to_lo(), deref.clone()),
126+
(rhs_span, deref),
127+
],
128+
Applicability::MachineApplicable,
129+
);
130+
}
131+
}
132+
}
133+
}
134+
_ => {}
135+
}
136+
}
137+
}
138+
}
139+
}
140+
141+
err
86142
}
87143
}
88144

0 commit comments

Comments
 (0)
This repository has been archived.