Skip to content

Commit

Permalink
Auto merge of #68078 - Centril:rollup-qvq052k, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #66463 (Point at opaque and closure type definitions in type errors)
 - #67501 (Reduce special treatment for zsts)
 - #67820 (Parse the syntax described in RFC 2632)
 - #67922 (rustc_ast_lowering: misc cleanup & rustc dep reductions)
 - #68071 (Extend support of `_` in type parameters)
 - #68073 (expect `fn` after `const unsafe` / `const extern`)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Jan 10, 2020
2 parents 72b2bd5 + 6f3f1c5 commit 2d8d559
Show file tree
Hide file tree
Showing 97 changed files with 2,072 additions and 1,038 deletions.
2 changes: 1 addition & 1 deletion src/librustc/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use crate::ty::fold::TypeFoldable;
use crate::ty::subst::{GenericArg, GenericArgKind};
use crate::ty::{self, BoundVar, Ty, TyCtxt};
use crate::util::captures::Captures;
use rustc_data_structures::captures::Captures;
use rustc_index::vec::Idx;
use rustc_index::vec::IndexVec;
use rustc_span::DUMMY_SP;
Expand Down
144 changes: 139 additions & 5 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,12 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::Node;

use errors::{struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString};
use errors::{
pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString,
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_error_codes::*;
use rustc_span::{Pos, Span};
use rustc_span::{DesugaringKind, Pos, Span};
use rustc_target::spec::abi;
use std::{cmp, fmt};

Expand Down Expand Up @@ -1289,6 +1292,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
mut values: Option<ValuePairs<'tcx>>,
terr: &TypeError<'tcx>,
) {
let span = cause.span(self.tcx);

// For some types of errors, expected-found does not make
// sense, so just ignore the values we were given.
match terr {
Expand All @@ -1298,6 +1303,100 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => {}
}

struct OpaqueTypesVisitor<'tcx> {
types: FxHashMap<TyCategory, FxHashSet<Span>>,
expected: FxHashMap<TyCategory, FxHashSet<Span>>,
found: FxHashMap<TyCategory, FxHashSet<Span>>,
ignore_span: Span,
tcx: TyCtxt<'tcx>,
}

impl<'tcx> OpaqueTypesVisitor<'tcx> {
fn visit_expected_found(
tcx: TyCtxt<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
ignore_span: Span,
) -> Self {
let mut types_visitor = OpaqueTypesVisitor {
types: Default::default(),
expected: Default::default(),
found: Default::default(),
ignore_span,
tcx,
};
// The visitor puts all the relevant encountered types in `self.types`, but in
// here we want to visit two separate types with no relation to each other, so we
// move the results from `types` to `expected` or `found` as appropriate.
expected.visit_with(&mut types_visitor);
std::mem::swap(&mut types_visitor.expected, &mut types_visitor.types);
found.visit_with(&mut types_visitor);
std::mem::swap(&mut types_visitor.found, &mut types_visitor.types);
types_visitor
}

fn report(&self, err: &mut DiagnosticBuilder<'_>) {
self.add_labels_for_types(err, "expected", &self.expected);
self.add_labels_for_types(err, "found", &self.found);
}

fn add_labels_for_types(
&self,
err: &mut DiagnosticBuilder<'_>,
target: &str,
types: &FxHashMap<TyCategory, FxHashSet<Span>>,
) {
for (key, values) in types.iter() {
let count = values.len();
let kind = key.descr();
for sp in values {
err.span_label(
*sp,
format!(
"{}{}{} {}{}",
if sp.is_desugaring(DesugaringKind::Async) {
"the `Output` of this `async fn`'s "
} else if count == 1 {
"the "
} else {
""
},
if count > 1 { "one of the " } else { "" },
target,
kind,
pluralize!(count),
),
);
}
}
}
}

impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypesVisitor<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
if let Some((kind, def_id)) = TyCategory::from_ty(t) {
let span = self.tcx.def_span(def_id);
// Avoid cluttering the output when the "found" and error span overlap:
//
// error[E0308]: mismatched types
// --> $DIR/issue-20862.rs:2:5
// |
// LL | |y| x + y
// | ^^^^^^^^^
// | |
// | the found closure
// | expected `()`, found closure
// |
// = note: expected unit type `()`
// found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
if !self.ignore_span.overlaps(span) {
self.types.entry(kind).or_default().insert(span);
}
}
t.super_visit_with(self)
}
}

debug!("note_type_err(diag={:?})", diag);
let (expected_found, exp_found, is_simple_error) = match values {
None => (None, None, false),
Expand All @@ -1306,6 +1405,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ValuePairs::Types(exp_found) => {
let is_simple_err =
exp_found.expected.is_simple_text() && exp_found.found.is_simple_text();
OpaqueTypesVisitor::visit_expected_found(
self.tcx,
exp_found.expected,
exp_found.found,
span,
)
.report(diag);

(is_simple_err, Some(exp_found))
}
Expand All @@ -1323,8 +1429,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
};

let span = cause.span(self.tcx);

// Ignore msg for object safe coercion
// since E0038 message will be printed
match terr {
Expand All @@ -1336,7 +1440,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
};

if let Some((expected, found)) = expected_found {
let expected_label = exp_found.map_or("type".into(), |ef| ef.expected.prefix_string());
let found_label = exp_found.map_or("type".into(), |ef| ef.found.prefix_string());
Expand Down Expand Up @@ -1933,3 +2036,34 @@ impl<'tcx> ObligationCause<'tcx> {
}
}
}

/// This is a bare signal of what kind of type we're dealing with. `ty::TyKind` tracks
/// extra information about each type, but we only care about the category.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
crate enum TyCategory {
Closure,
Opaque,
Generator,
Foreign,
}

impl TyCategory {
fn descr(&self) -> &'static str {
match self {
Self::Closure => "closure",
Self::Opaque => "opaque type",
Self::Generator => "generator",
Self::Foreign => "foreign type",
}
}

pub fn from_ty(ty: Ty<'_>) -> Option<(Self, DefId)> {
match ty.kind {
ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
ty::Opaque(def_id, _) => Some((Self::Opaque, def_id)),
ty::Generator(def_id, ..) => Some((Self::Generator, def_id)),
ty::Foreign(def_id) => Some((Self::Foreign, def_id)),
_ => None,
}
}
}
2 changes: 1 addition & 1 deletion src/librustc/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::infer::{GenericKind, VerifyBound};
use crate::traits;
use crate::ty::subst::{InternalSubsts, Subst};
use crate::ty::{self, Ty, TyCtxt};
use crate::util::captures::Captures;
use rustc_data_structures::captures::Captures;
use rustc_hir::def_id::DefId;

/// The `TypeOutlives` struct has the job of "lowering" a `T: 'a`
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ pub mod ty;

pub mod util {
pub mod bug;
pub mod captures;
pub mod common;
}

Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use crate::hir::map as hir_map;
use crate::hir::map::definitions::{DefKey, DefPathTable};
use crate::session::search_paths::PathKind;
use crate::session::{CrateDisambiguator, Session};
use crate::ty::{self, TyCtxt};
use crate::session::CrateDisambiguator;
use crate::ty::TyCtxt;

use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{self, MetadataRef};
Expand Down Expand Up @@ -208,7 +208,6 @@ pub trait CrateStore {
fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics;

// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
Expand Down
29 changes: 23 additions & 6 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
TraitNotObjectSafe,
};

use crate::infer::error_reporting::TypeAnnotationNeeded as ErrorCode;
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{self, InferCtxt};
use crate::mir::interpret::ErrorHandled;
Expand Down Expand Up @@ -446,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
flags.push((sym::from_method, Some(method.to_string())));
}
}
if let Some(t) = self.get_parent_trait_ref(&obligation.cause.code) {
if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) {
flags.push((sym::parent_trait, Some(t)));
}

Expand Down Expand Up @@ -665,13 +665,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

/// Gets the parent trait chain start
fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
fn get_parent_trait_ref(
&self,
code: &ObligationCauseCode<'tcx>,
) -> Option<(String, Option<Span>)> {
match code {
&ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
match self.get_parent_trait_ref(&data.parent_code) {
Some(t) => Some(t),
None => Some(parent_trait_ref.skip_binder().self_ty().to_string()),
None => {
let ty = parent_trait_ref.skip_binder().self_ty();
let span =
TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id));
Some((ty.to_string(), span))
}
}
}
_ => None,
Expand Down Expand Up @@ -719,9 +727,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return;
}
let trait_ref = trait_predicate.to_poly_trait_ref();
let (post_message, pre_message) = self
let (post_message, pre_message, type_def) = self
.get_parent_trait_ref(&obligation.cause.code)
.map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
.map(|(t, s)| {
(
format!(" in `{}`", t),
format!("within `{}`, ", t),
s.map(|s| (format!("within this `{}`", t), s)),
)
})
.unwrap_or_default();

let OnUnimplementedNote { message, label, note, enclosing_scope } =
Expand Down Expand Up @@ -795,6 +809,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} else {
err.span_label(span, explanation);
}
if let Some((msg, span)) = type_def {
err.span_label(span, &msg);
}
if let Some(ref s) = note {
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
err.note(s.as_str());
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use crate::ty::fold::{TypeFoldable, TypeFolder};
use crate::ty::subst::{InternalSubsts, Subst};
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt};
use crate::util::common::FN_OUTPUT_NAME;
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;
Expand Down Expand Up @@ -1364,7 +1363,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
projection_ty: ty::ProjectionTy::from_ref_and_name(
tcx,
trait_ref,
Ident::with_dummy_span(FN_OUTPUT_NAME),
Ident::with_dummy_span(rustc_hir::FN_OUTPUT_NAME),
),
ty: ret_type,
});
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use crate::ty::layout::VariantIdx;
use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
use crate::ty::util::{Discr, IntTypeExt};
use crate::ty::walk::TypeWalker;
use crate::util::captures::Captures;
use arena::SyncDroplessArena;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ use crate::ty::layout::VariantIdx;
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
use crate::util::captures::Captures;
use polonius_engine::Atom;
use rustc_data_structures::captures::Captures;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;

use polonius_engine::Atom;
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Symbol};
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/util/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ use rustc_data_structures::sync::Lock;
use std::fmt::Debug;
use std::time::{Duration, Instant};

use rustc_span::symbol::{sym, Symbol};

#[cfg(test)]
mod tests;

// The name of the associated type for `Fn` return types.
pub const FN_OUTPUT_NAME: Symbol = sym::Output;

pub use errors::ErrorReported;

pub fn to_readable_str(mut val: usize) -> String {
Expand Down
17 changes: 10 additions & 7 deletions src/librustc_ast_lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,16 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
}

impl<'a, 'lowering, 'hir> ItemLowerer<'a, 'lowering, 'hir> {
fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
where
F: FnOnce(&mut Self),
{
impl ItemLowerer<'_, '_, '_> {
fn with_trait_impl_ref(&mut self, impl_ref: &Option<TraitRef>, f: impl FnOnce(&mut Self)) {
let old = self.lctx.is_in_trait_impl;
self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { false } else { true };
self.lctx.is_in_trait_impl = if let &None = impl_ref { false } else { true };
f(self);
self.lctx.is_in_trait_impl = old;
}
}

impl<'a, 'lowering, 'hir> Visitor<'a> for ItemLowerer<'a, 'lowering, 'hir> {
impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
let hir_id = self.lctx.lower_node_id(n);

Expand Down Expand Up @@ -71,6 +68,12 @@ impl<'a, 'lowering, 'hir> Visitor<'a> for ItemLowerer<'a, 'lowering, 'hir> {
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
let this = &mut ItemLowerer { lctx: this };
if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind {
if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) {
this.lctx
.diagnostic()
.span_err(item.span, "const trait impls are not yet implemented");
}

this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item));
} else {
visit::walk_item(this, item);
Expand Down
Loading

0 comments on commit 2d8d559

Please sign in to comment.