Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 9 pull requests #64115

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
5a446c1
Fix `window.hashchange is not a function`
fmckeogh Aug 21, 2019
cab607e
Emit a single error on if expr with expectation and no else clause
estebank Sep 1, 2019
aae2b24
deduplicate code
estebank Sep 1, 2019
a9ce33c
Account for arbitrary self types in E0599
estebank Sep 1, 2019
84ccbe2
librustc_errors: Extract sugg/subst handling into method
phansch Sep 1, 2019
35c9e5f
Fix const_err with `-(-0.0)`
JohnTitor Sep 1, 2019
3a6aada
Add `opt-level` check
JohnTitor Sep 1, 2019
ab12dfe
following the same style
Sep 1, 2019
4a0872b
Add `overflow_check` check
JohnTitor Sep 1, 2019
f53c217
review comments
estebank Sep 1, 2019
8e9825a
Fix overflow_check
JohnTitor Sep 1, 2019
141f5a7
review comments
estebank Sep 1, 2019
0cd9c16
Fix condition and tests' flags
JohnTitor Sep 1, 2019
a937d8c
Fix tests again
JohnTitor Sep 1, 2019
991f436
Fix regex replacement in theme detection
GuillaumeGomez Sep 2, 2019
52c68d1
Add buffer abstraction
Mark-Simulacrum Aug 27, 2019
3c83d64
Migrate top-level rendering to Buffer
Mark-Simulacrum Aug 30, 2019
a076816
Create buffers in top-level rendering
Mark-Simulacrum Aug 30, 2019
8850cb5
Remove needless clone of layout
Mark-Simulacrum Aug 30, 2019
a3539f9
Move constant parameters to render to Layout struct
Mark-Simulacrum Aug 30, 2019
d869748
Replace writeln!/write! with push_str
Mark-Simulacrum Aug 31, 2019
14fcaa1
Remove unnecessary Buffer in layout::render
Mark-Simulacrum Aug 31, 2019
ca2801f
Move sidebar to Buffer-printing
Mark-Simulacrum Aug 31, 2019
2367975
Implement Print for FnOnce(&mut Buffer)
Mark-Simulacrum Aug 31, 2019
8c06e79
Delete Sidebar struct in favor of FnOnce impl
Mark-Simulacrum Aug 31, 2019
6ab9b32
De-indent all fmt::Display impls for later replacement to functions
Mark-Simulacrum Aug 31, 2019
6165313
layout::render takes Print instead of fmt::Display
Mark-Simulacrum Aug 31, 2019
a57f00d
Move Source to Buffer
Mark-Simulacrum Aug 31, 2019
cd92ed2
Settings to function
Mark-Simulacrum Aug 31, 2019
b2eb65b
AllTypes to function
Mark-Simulacrum Aug 31, 2019
31391ca
Item to function
Mark-Simulacrum Aug 31, 2019
a9c6ef6
Move to buffers throughout print_item
Mark-Simulacrum Aug 31, 2019
dd323f8
Emit error on intrinsic to fn ptr casts
Mark-Simulacrum Sep 2, 2019
cdc821f
Rollup merge of #63774 - chocol4te:fix_63707, r=GuillaumeGomez
Centril Sep 3, 2019
85baeec
Rollup merge of #64044 - Mark-Simulacrum:rustdoc-clean-2, r=Guillaume…
Centril Sep 3, 2019
781f533
Rollup merge of #64049 - estebank:if-else-type-err, r=Centril
Centril Sep 3, 2019
43eac83
Rollup merge of #64056 - estebank:arbitrary-self-types, r=Centril
Centril Sep 3, 2019
dd8d419
Rollup merge of #64058 - phansch:refactor_out_method, r=estebank
Centril Sep 3, 2019
c1832a6
Rollup merge of #64063 - JohnTitor:fix-const-err, r=oli-obk
Centril Sep 3, 2019
ed13e27
Rollup merge of #64071 - guanqun:style-fix, r=Centril
Centril Sep 3, 2019
3e427d9
Rollup merge of #64096 - GuillaumeGomez:theme-regex-fix, r=Mark-Simul…
Centril Sep 3, 2019
0de3668
Rollup merge of #64104 - Mark-Simulacrum:intrinsic-fn-ptr-ice, r=este…
Centril Sep 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,9 @@ impl<'tcx> ObligationCause<'tcx> {
TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => {
Error0644("closure/generator type that references itself")
}
TypeError::IntrinsicCast => {
Error0308("cannot coerce intrinsics to function pointers")
}
_ => Error0308("mismatched types"),
},
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,12 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_generic_adt(def_id, ty)
}

#[inline]
pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem) -> Ty<'tcx> {
let def_id = self.require_lang_item(item, None);
self.mk_generic_adt(def_id, ty)
}

#[inline]
pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub enum TypeError<'tcx> {
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),

ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),

IntrinsicCast,
}

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
Expand Down Expand Up @@ -179,6 +181,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
ConstMismatch(ref values) => {
write!(f, "expected `{}`, found `{}`", values.expected, values.found)
}
IntrinsicCast => {
write!(f, "cannot coerce intrinsics to function pointers")
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
Sorts(ref x) => return tcx.lift(x).map(Sorts),
ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
IntrinsicCast => IntrinsicCast,
})
}
}
Expand Down Expand Up @@ -1338,6 +1339,7 @@ EnumTypeFoldableImpl! {
(ty::error::TypeError::Sorts)(x),
(ty::error::TypeError::ExistentialMismatch)(x),
(ty::error::TypeError::ConstMismatch)(x),
(ty::error::TypeError::IntrinsicCast),
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/librustc_errors/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ pub struct AnnotateSnippetEmitterWriter {
impl Emitter for AnnotateSnippetEmitterWriter {
/// The entry point for the diagnostics generation
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
let primary_span = db.span.clone();
let children = db.children.clone();
// FIXME(#59346): Collect suggestions (see emitter.rs)
let suggestions: &[_] = &[];
let (primary_span, suggestions) = self.primary_span_formatted(&db);

// FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs

Expand Down
40 changes: 31 additions & 9 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,25 @@ pub trait Emitter {
fn should_show_explain(&self) -> bool {
true
}
}

impl Emitter for EmitterWriter {
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
/// Formats the substitutions of the primary_span
///
/// The are a lot of conditions to this method, but in short:
///
/// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
/// we format the `help` suggestion depending on the content of the
/// substitutions. In that case, we return the modified span only.
///
/// * If the current `Diagnostic` has multiple suggestions,
/// we return the original `primary_span` and the original suggestions.
fn primary_span_formatted<'a>(
&mut self,
db: &'a DiagnosticBuilder<'_>
) -> (MultiSpan, &'a [CodeSuggestion]) {
let mut primary_span = db.span.clone();
let mut children = db.children.clone();
let mut suggestions: &[_] = &[];

if let Some((sugg, rest)) = db.suggestions.split_first() {
if rest.is_empty() &&
// ^ if there is only one suggestion
// don't display multi-suggestions as labels
sugg.substitutions.len() == 1 &&
// don't display multipart suggestions as labels
Expand All @@ -216,21 +225,34 @@ impl Emitter for EmitterWriter {
{
let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
// This substitution is only removal or we explicitly don't want to show the
// code inline, don't show it
// This substitution is only removal OR we explicitly don't want to show the
// code inline (`hide_inline`). Therefore, we don't show the substitution.
format!("help: {}", sugg.msg)
} else {
// Show the default suggestion text with the substitution
format!("help: {}: `{}`", sugg.msg, substitution)
};
primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);

// We return only the modified primary_span
(primary_span, &[])
} else {
// if there are multiple suggestions, print them all in full
// to be consistent. We could try to figure out if we can
// make one (or the first one) inline, but that would give
// undue importance to a semi-random suggestion
suggestions = &db.suggestions;
(primary_span, &db.suggestions)
}
} else {
(primary_span, &db.suggestions)
}
}
}

impl Emitter for EmitterWriter {
fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
let mut children = db.children.clone();
let (mut primary_span, suggestions) = self.primary_span_formatted(&db);

self.fix_multispans_in_std_macros(&mut primary_span,
&mut children,
Expand Down
13 changes: 9 additions & 4 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,13 +405,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}

let arg = self.eval_operand(arg, source_info)?;
let oflo_check = self.tcx.sess.overflow_checks();
let val = self.use_ecx(source_info, |this| {
let prim = this.ecx.read_immediate(arg)?;
match op {
UnOp::Neg => {
// Need to do overflow check here: For actual CTFE, MIR
// generation emits code that does this before calling the op.
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
// We check overflow in debug mode already
// so should only check in release mode.
if !oflo_check
&& prim.layout.ty.is_signed()
&& prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
throw_panic!(OverflowNeg)
}
}
Expand Down Expand Up @@ -485,7 +488,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Scalar::from_bool(overflow).into(),
)
} else {
if overflow {
// We check overflow in debug mode already
// so should only check in release mode.
if !self.tcx.sess.overflow_checks() && overflow {
let err = err_panic!(Overflow(op)).into();
let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
return None;
Expand Down
30 changes: 21 additions & 9 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

self.diverges.set(pats_diverge);
let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
let arm_ty = if source_if && if_no_else && i != 0 && self.if_fallback_coercion(
expr.span,
&arms[0].body,
&mut coercion,
) {
tcx.types.err
} else {
// Only call this if this is not an `if` expr with an expected type and no `else`
// clause to avoid duplicated type errors. (#60254)
self.check_expr_with_expectation(&arm.body, expected)
};
all_arms_diverge &= self.diverges.get();

let span = expr.span;

if source_if {
let then_expr = &arms[0].body;
match (i, if_no_else) {
(0, _) => coercion.coerce(self, &self.misc(span), &arm.body, arm_ty),
(_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
(0, _) => coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty),
(_, true) => {} // Handled above to avoid duplicated type errors (#60254).
(_, _) => {
let then_ty = prior_arm_ty.unwrap();
let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty);
coercion.coerce(self, &cause, &arm.body, arm_ty);
}
}
Expand All @@ -139,7 +146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// The reason for the first arm to fail is not that the match arms diverge,
// but rather that there's a prior obligation that doesn't hold.
0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
_ => (span, ObligationCauseCode::MatchExpressionArm {
_ => (expr.span, ObligationCauseCode::MatchExpressionArm {
arm_span,
source: match_src,
prior_arms: other_arms.clone(),
Expand Down Expand Up @@ -180,16 +187,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

/// Handle the fallback arm of a desugared if(-let) like a missing else.
///
/// Returns `true` if there was an error forcing the coercion to the `()` type.
fn if_fallback_coercion(
&self,
span: Span,
then_expr: &'tcx hir::Expr,
coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm>,
) {
) -> bool {
// If this `if` expr is the parent's function return expr,
// the cause of the type coercion is the return type, point at it. (#25228)
let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
let mut error = false;
coercion.coerce_forced_unit(self, &cause, &mut |err| {
if let Some((span, msg)) = &ret_reason {
err.span_label(*span, msg.as_str());
Expand All @@ -200,7 +210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
err.note("`if` expressions without `else` evaluate to `()`");
err.help("consider adding an `else` block that evaluates to the expected type");
error = true;
}, ret_reason.is_none());
error
}

fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_typeck/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut};
use rustc::ty::subst::SubstsRef;
use rustc::ty::adjustment::AllowTwoPhase;
use rustc::ty::cast::{CastKind, CastTy};
use rustc::ty::error::TypeError;
use rustc::middle::lang_items;
use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -461,6 +462,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
self.expr_ty,
fcx.tcx.mk_fn_ptr(f),
AllowTwoPhase::No);
if let Err(TypeError::IntrinsicCast) = res {
return Err(CastError::IllegalCast);
}
if res.is_err() {
return Err(CastError::NonScalar);
}
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use std::ops::Deref;
use syntax::feature_gate;
use syntax::symbol::sym;
use syntax_pos;
use rustc_target::spec::abi::Abi;

struct Coerce<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
Expand Down Expand Up @@ -689,6 +690,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
match b.sty {
ty::FnPtr(_) => {
let a_sig = a.fn_sig(self.tcx);
// Intrinsics are not coercible to function pointers
if a_sig.abi() == Abi::RustIntrinsic ||
a_sig.abi() == Abi::PlatformIntrinsic {
return Err(TypeError::IntrinsicCast);
}
let InferOk { value: a_sig, mut obligations } =
self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig);

Expand Down
Loading