Skip to content

Commit

Permalink
Auto merge of #64902 - Centril:rollup-1i431vs, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Sep 29, 2019
2 parents 06c6894 + 50940ae commit 8431f26
Show file tree
Hide file tree
Showing 60 changed files with 881 additions and 232 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -33,7 +33,7 @@ or reading the [rustc guide][rustcguidebuild].
* `curl`
* `git`
* `ssl` which comes in `libssl-dev` or `openssl-devel`
* `pkg-config` if you are on compiling on Linux and targeting Linux
* `pkg-config` if you are compiling on Linux and targeting Linux

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

Expand Down
23 changes: 11 additions & 12 deletions src/librustc/hir/lowering/expr.rs
Expand Up @@ -1037,10 +1037,9 @@ impl LoweringContext<'_> {
) -> hir::Expr {
// expand <head>
let mut head = self.lower_expr(head);
let head_sp = head.span;
let desugared_span = self.mark_span_with_reason(
DesugaringKind::ForLoop,
head_sp,
head.span,
None,
);
head.span = desugared_span;
Expand Down Expand Up @@ -1086,21 +1085,21 @@ impl LoweringContext<'_> {

// `match ::std::iter::Iterator::next(&mut iter) { ... }`
let match_expr = {
let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid));
let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
let next_path = &[sym::iter, sym::Iterator, sym::next];
let next_expr = P(self.expr_call_std_path(
head_sp,
desugared_span,
next_path,
hir_vec![ref_mut_iter],
));
let arms = hir_vec![pat_arm, break_arm];

self.expr_match(head_sp, next_expr, arms, hir::MatchSource::ForLoopDesugar)
self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
};
let match_stmt = self.stmt_expr(head_sp, match_expr);
let match_stmt = self.stmt_expr(desugared_span, match_expr);

let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid));
let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid));

// `let mut __next`
let next_let = self.stmt_let_pat(
Expand All @@ -1115,7 +1114,7 @@ impl LoweringContext<'_> {
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
head_sp,
desugared_span,
Some(next_expr),
pat,
hir::LocalSource::ForLoopDesugar,
Expand Down Expand Up @@ -1152,14 +1151,14 @@ impl LoweringContext<'_> {
let into_iter_path =
&[sym::iter, sym::IntoIterator, sym::into_iter];
P(self.expr_call_std_path(
head_sp,
desugared_span,
into_iter_path,
hir_vec![head],
))
};

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

/// Desugar `ExprKind::Try` from: `<expr>?` into:
Expand Down
26 changes: 26 additions & 0 deletions src/librustc/hir/map/mod.rs
Expand Up @@ -818,6 +818,32 @@ impl<'hir> Map<'hir> {
CRATE_HIR_ID
}

/// When on a match arm tail expression or on a match arm, give back the enclosing `match`
/// expression.
///
/// Used by error reporting when there's a type error in a match arm caused by the `match`
/// expression needing to be unit.
pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&Expr> {
for (_, node) in ParentHirIterator::new(hir_id, &self) {
match node {
Node::Item(_) |
Node::ForeignItem(_) |
Node::TraitItem(_) |
Node::ImplItem(_) => break,
Node::Expr(expr) => match expr.kind {
ExprKind::Match(_, _, _) => return Some(expr),
_ => {}
},
Node::Stmt(stmt) => match stmt.kind {
StmtKind::Local(_) => break,
_ => {}
}
_ => {}
}
}
None
}

/// Returns the nearest enclosing scope. A scope is roughly an item or block.
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option<HirId> {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/mir/interpret/mod.rs
Expand Up @@ -101,7 +101,7 @@ pub use self::error::{
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo,
};

pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes};

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

Expand Down
15 changes: 15 additions & 0 deletions src/librustc/mir/interpret/value.rs
Expand Up @@ -611,3 +611,18 @@ impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});

/// Gets the bytes of a constant slice value.
pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
if let ConstValue::Slice { data, start, end } = val {
let len = end - start;
data.get_bytes(
cx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
Size::from_bytes(len as u64),
).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
} else {
bug!("expected const slice, but found another const value");
}
}
17 changes: 15 additions & 2 deletions src/librustc/ty/relate.rs
Expand Up @@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
use crate::mir::interpret::{ConstValue, Scalar};
use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
Expand Down Expand Up @@ -584,7 +584,20 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
// saying that we're not handling it intentionally.

// FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`.
(a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
let a_bytes = get_slice_bytes(&tcx, a_val);
let b_bytes = get_slice_bytes(&tcx, b_val);
if a_bytes == b_bytes {
Ok(tcx.mk_const(ty::Const {
val: a_val,
ty: a.ty,
}))
} else {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
}

// FIXME(const_generics): handle `ConstValue::ByRef`.

// FIXME(const_generics): this is wrong, as it is a projection
(ConstValue::Unevaluated(a_def_id, a_substs),
Expand Down
29 changes: 6 additions & 23 deletions src/librustc_mir/hair/pattern/mod.rs
Expand Up @@ -13,12 +13,12 @@ use crate::hair::constant::*;
use rustc::lint;
use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend};
use rustc::traits::{ObligationCause, PredicateObligation};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, GenericArg};
use rustc::ty::layout::{VariantIdx, Size};
use rustc::ty::layout::VariantIdx;
use rustc::hir::{self, RangeEnd};
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
Expand Down Expand Up @@ -1526,27 +1526,10 @@ pub fn compare_const_vals<'tcx>(

if let ty::Str = ty.kind {
match (a.val, b.val) {
(
ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
) => {
let len_a = end_a - offset_a;
let len_b = end_b - offset_b;
let a = alloc_a.get_bytes(
&tcx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
Size::from_bytes(len_a as u64),
);
let b = alloc_b.get_bytes(
&tcx,
// invent a pointer, only the offset is relevant anyway
Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
Size::from_bytes(len_b as u64),
);
if let (Ok(a), Ok(b)) = (a, b) {
return from_bool(a == b);
}
(ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
let a_bytes = get_slice_bytes(&tcx, a.val);
let b_bytes = get_slice_bytes(&tcx, b.val);
return from_bool(a_bytes == b_bytes);
}
_ => (),
}
Expand Down
22 changes: 14 additions & 8 deletions src/librustc_resolve/late/diagnostics.rs
Expand Up @@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => false,
};

let mut bad_struct_syntax_suggestion = || {
let mut bad_struct_syntax_suggestion = |def_id: DefId| {
let (followed_by_brace, closing_brace) = self.followed_by_brace(span);
let mut suggested = false;
match source {
Expand All @@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => {}
}
if !suggested {
if let Some(span) = self.r.definitions.opt_span(def_id) {
err.span_label(span, &format!("`{}` defined here", path_str));
}
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
Expand Down Expand Up @@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> {
);
}
} else {
bad_struct_syntax_suggestion();
bad_struct_syntax_suggestion(def_id);
}
}
(Res::Def(DefKind::Union, _), _) |
(Res::Def(DefKind::Variant, _), _) |
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
bad_struct_syntax_suggestion();
(Res::Def(DefKind::Union, def_id), _) |
(Res::Def(DefKind::Variant, def_id), _) |
(Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => {
bad_struct_syntax_suggestion(def_id);
}
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
if let Some(span) = self.r.definitions.opt_span(def_id) {
err.span_label(span, &format!("`{}` defined here", path_str));
}
err.span_label(
span,
format!("did you mean `{} ( /* fields */ )`?", path_str),
format!("did you mean `{}( /* fields */ )`?", path_str),
);
}
(Res::SelfTy(..), _) if ns == ValueNS => {
Expand Down
8 changes: 5 additions & 3 deletions src/librustc_typeck/check/_match.rs
Expand Up @@ -36,7 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
//
// FIXME(60707): Consider removing hack with principled solution.
self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {})
} else {
self.demand_discriminant_type(arms, discrim)
};
Expand Down Expand Up @@ -106,7 +106,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(g) = &arm.guard {
self.diverges.set(pats_diverge);
match g {
hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
hir::Guard::If(e) => {
self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
}
};
}

Expand Down Expand Up @@ -442,7 +444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::TypeInference,
span: discrim.span,
});
self.check_expr_has_type_or_error(discrim, discrim_ty);
self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {});
discrim_ty
}
}
Expand Down

0 comments on commit 8431f26

Please sign in to comment.