Skip to content

Commit 8431f26

Browse files
committed
Auto merge of #64902 - Centril:rollup-1i431vs, r=Centril
Rollup of 6 pull requests Successful merges: - #64691 (Point at definition when misusing ADT) - #64735 (Add long error explanation for E0533) - #64825 (Point at enclosing match when expecting `()` in arm) - #64858 (Add support for relating slices in `super_relate_consts`) - #64894 (syntax: fix dropping of attribute on first param of non-method assocated fn) - #64898 (fixed typo) Failed merges: r? @ghost
2 parents 06c6894 + 50940ae commit 8431f26

File tree

60 files changed

+881
-232
lines changed

Some content is hidden

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

60 files changed

+881
-232
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ or reading the [rustc guide][rustcguidebuild].
3333
* `curl`
3434
* `git`
3535
* `ssl` which comes in `libssl-dev` or `openssl-devel`
36-
* `pkg-config` if you are on compiling on Linux and targeting Linux
36+
* `pkg-config` if you are compiling on Linux and targeting Linux
3737

3838
2. Clone the [source] with `git`:
3939

src/librustc/hir/lowering/expr.rs

+11-12
Original file line numberDiff line numberDiff line change
@@ -1037,10 +1037,9 @@ impl LoweringContext<'_> {
10371037
) -> hir::Expr {
10381038
// expand <head>
10391039
let mut head = self.lower_expr(head);
1040-
let head_sp = head.span;
10411040
let desugared_span = self.mark_span_with_reason(
10421041
DesugaringKind::ForLoop,
1043-
head_sp,
1042+
head.span,
10441043
None,
10451044
);
10461045
head.span = desugared_span;
@@ -1086,21 +1085,21 @@ impl LoweringContext<'_> {
10861085

10871086
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
10881087
let match_expr = {
1089-
let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
1090-
let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
1088+
let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid));
1089+
let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
10911090
let next_path = &[sym::iter, sym::Iterator, sym::next];
10921091
let next_expr = P(self.expr_call_std_path(
1093-
head_sp,
1092+
desugared_span,
10941093
next_path,
10951094
hir_vec![ref_mut_iter],
10961095
));
10971096
let arms = hir_vec![pat_arm, break_arm];
10981097

1099-
self.expr_match(head_sp, next_expr, arms, hir::MatchSource::ForLoopDesugar)
1098+
self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
11001099
};
1101-
let match_stmt = self.stmt_expr(head_sp, match_expr);
1100+
let match_stmt = self.stmt_expr(desugared_span, match_expr);
11021101

1103-
let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid));
1102+
let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid));
11041103

11051104
// `let mut __next`
11061105
let next_let = self.stmt_let_pat(
@@ -1115,7 +1114,7 @@ impl LoweringContext<'_> {
11151114
let pat = self.lower_pat(pat);
11161115
let pat_let = self.stmt_let_pat(
11171116
ThinVec::new(),
1118-
head_sp,
1117+
desugared_span,
11191118
Some(next_expr),
11201119
pat,
11211120
hir::LocalSource::ForLoopDesugar,
@@ -1152,14 +1151,14 @@ impl LoweringContext<'_> {
11521151
let into_iter_path =
11531152
&[sym::iter, sym::IntoIterator, sym::into_iter];
11541153
P(self.expr_call_std_path(
1155-
head_sp,
1154+
desugared_span,
11561155
into_iter_path,
11571156
hir_vec![head],
11581157
))
11591158
};
11601159

11611160
let match_expr = P(self.expr_match(
1162-
head_sp,
1161+
desugared_span,
11631162
into_iter_expr,
11641163
hir_vec![iter_arm],
11651164
hir::MatchSource::ForLoopDesugar,
@@ -1171,7 +1170,7 @@ impl LoweringContext<'_> {
11711170
// surrounding scope of the `match` since the `match` is not a terminating scope.
11721171
//
11731172
// Also, add the attributes to the outer returned expr node.
1174-
self.expr_drop_temps(head_sp, match_expr, e.attrs.clone())
1173+
self.expr_drop_temps(desugared_span, match_expr, e.attrs.clone())
11751174
}
11761175

11771176
/// Desugar `ExprKind::Try` from: `<expr>?` into:

src/librustc/hir/map/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,32 @@ impl<'hir> Map<'hir> {
818818
CRATE_HIR_ID
819819
}
820820

821+
/// When on a match arm tail expression or on a match arm, give back the enclosing `match`
822+
/// expression.
823+
///
824+
/// Used by error reporting when there's a type error in a match arm caused by the `match`
825+
/// expression needing to be unit.
826+
pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&Expr> {
827+
for (_, node) in ParentHirIterator::new(hir_id, &self) {
828+
match node {
829+
Node::Item(_) |
830+
Node::ForeignItem(_) |
831+
Node::TraitItem(_) |
832+
Node::ImplItem(_) => break,
833+
Node::Expr(expr) => match expr.kind {
834+
ExprKind::Match(_, _, _) => return Some(expr),
835+
_ => {}
836+
},
837+
Node::Stmt(stmt) => match stmt.kind {
838+
StmtKind::Local(_) => break,
839+
_ => {}
840+
}
841+
_ => {}
842+
}
843+
}
844+
None
845+
}
846+
821847
/// Returns the nearest enclosing scope. A scope is roughly an item or block.
822848
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> {
823849
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {

src/librustc/mir/interpret/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub use self::error::{
101101
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo,
102102
};
103103

104-
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
104+
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes};
105105

106106
pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
107107

src/librustc/mir/interpret/value.rs

+15
Original file line numberDiff line numberDiff line change
@@ -611,3 +611,18 @@ impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
611611
Scalar(v),
612612
Undef
613613
});
614+
615+
/// Gets the bytes of a constant slice value.
616+
pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
617+
if let ConstValue::Slice { data, start, end } = val {
618+
let len = end - start;
619+
data.get_bytes(
620+
cx,
621+
// invent a pointer, only the offset is relevant anyway
622+
Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
623+
Size::from_bytes(len as u64),
624+
).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
625+
} else {
626+
bug!("expected const slice, but found another const value");
627+
}
628+
}

src/librustc/ty/relate.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
88
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
99
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
1010
use crate::ty::error::{ExpectedFound, TypeError};
11-
use crate::mir::interpret::{ConstValue, Scalar};
11+
use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar};
1212
use std::rc::Rc;
1313
use std::iter;
1414
use rustc_target::spec::abi;
@@ -584,7 +584,20 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
584584
// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
585585
// saying that we're not handling it intentionally.
586586

587-
// FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`.
587+
(a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
588+
let a_bytes = get_slice_bytes(&tcx, a_val);
589+
let b_bytes = get_slice_bytes(&tcx, b_val);
590+
if a_bytes == b_bytes {
591+
Ok(tcx.mk_const(ty::Const {
592+
val: a_val,
593+
ty: a.ty,
594+
}))
595+
} else {
596+
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
597+
}
598+
}
599+
600+
// FIXME(const_generics): handle `ConstValue::ByRef`.
588601

589602
// FIXME(const_generics): this is wrong, as it is a projection
590603
(ConstValue::Unevaluated(a_def_id, a_substs),

src/librustc_mir/hair/pattern/mod.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ use crate::hair::constant::*;
1313
use rustc::lint;
1414
use rustc::mir::{Field, BorrowKind, Mutability};
1515
use rustc::mir::{UserTypeProjection};
16-
use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
16+
use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend};
1717
use rustc::traits::{ObligationCause, PredicateObligation};
1818
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
1919
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
2020
use rustc::ty::subst::{SubstsRef, GenericArg};
21-
use rustc::ty::layout::{VariantIdx, Size};
21+
use rustc::ty::layout::VariantIdx;
2222
use rustc::hir::{self, RangeEnd};
2323
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
2424
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -1526,27 +1526,10 @@ pub fn compare_const_vals<'tcx>(
15261526

15271527
if let ty::Str = ty.kind {
15281528
match (a.val, b.val) {
1529-
(
1530-
ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
1531-
ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
1532-
) => {
1533-
let len_a = end_a - offset_a;
1534-
let len_b = end_b - offset_b;
1535-
let a = alloc_a.get_bytes(
1536-
&tcx,
1537-
// invent a pointer, only the offset is relevant anyway
1538-
Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
1539-
Size::from_bytes(len_a as u64),
1540-
);
1541-
let b = alloc_b.get_bytes(
1542-
&tcx,
1543-
// invent a pointer, only the offset is relevant anyway
1544-
Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
1545-
Size::from_bytes(len_b as u64),
1546-
);
1547-
if let (Ok(a), Ok(b)) = (a, b) {
1548-
return from_bool(a == b);
1549-
}
1529+
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
1530+
let a_bytes = get_slice_bytes(&tcx, a.val);
1531+
let b_bytes = get_slice_bytes(&tcx, b.val);
1532+
return from_bool(a_bytes == b_bytes);
15501533
}
15511534
_ => (),
15521535
}

src/librustc_resolve/late/diagnostics.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
348348
_ => false,
349349
};
350350

351-
let mut bad_struct_syntax_suggestion = || {
351+
let mut bad_struct_syntax_suggestion = |def_id: DefId| {
352352
let (followed_by_brace, closing_brace) = self.followed_by_brace(span);
353353
let mut suggested = false;
354354
match source {
@@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
374374
_ => {}
375375
}
376376
if !suggested {
377+
if let Some(span) = self.r.definitions.opt_span(def_id) {
378+
err.span_label(span, &format!("`{}` defined here", path_str));
379+
}
377380
err.span_label(
378381
span,
379382
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
@@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> {
437440
);
438441
}
439442
} else {
440-
bad_struct_syntax_suggestion();
443+
bad_struct_syntax_suggestion(def_id);
441444
}
442445
}
443-
(Res::Def(DefKind::Union, _), _) |
444-
(Res::Def(DefKind::Variant, _), _) |
445-
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
446-
bad_struct_syntax_suggestion();
446+
(Res::Def(DefKind::Union, def_id), _) |
447+
(Res::Def(DefKind::Variant, def_id), _) |
448+
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => {
449+
bad_struct_syntax_suggestion(def_id);
447450
}
448-
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
451+
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
452+
if let Some(span) = self.r.definitions.opt_span(def_id) {
453+
err.span_label(span, &format!("`{}` defined here", path_str));
454+
}
449455
err.span_label(
450456
span,
451-
format!("did you mean `{} ( /* fields */ )`?", path_str),
457+
format!("did you mean `{}( /* fields */ )`?", path_str),
452458
);
453459
}
454460
(Res::SelfTy(..), _) if ns == ValueNS => {

src/librustc_typeck/check/_match.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3636
// 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
3737
//
3838
// FIXME(60707): Consider removing hack with principled solution.
39-
self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
39+
self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {})
4040
} else {
4141
self.demand_discriminant_type(arms, discrim)
4242
};
@@ -106,7 +106,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
106106
if let Some(g) = &arm.guard {
107107
self.diverges.set(pats_diverge);
108108
match g {
109-
hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
109+
hir::Guard::If(e) => {
110+
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
111+
}
110112
};
111113
}
112114

@@ -442,7 +444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
442444
kind: TypeVariableOriginKind::TypeInference,
443445
span: discrim.span,
444446
});
445-
self.check_expr_has_type_or_error(discrim, discrim_ty);
447+
self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {});
446448
discrim_ty
447449
}
448450
}

0 commit comments

Comments
 (0)