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 6 pull requests #65851

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f293eb4
Use heuristics to suggest assignment
estebank Oct 18, 2019
fa0b721
Remove unnecessary error in test
estebank Oct 18, 2019
cdc5400
review comments and tweaks
estebank Oct 19, 2019
10ce36c
review comment: use `Default`
estebank Oct 19, 2019
93cac9c
rustc: add `Span`s to `inferred_outlives_of` predicates.
eddyb Oct 18, 2019
1ca8da4
rustc_typeck: compute better spans for inferred_outlives.
eddyb Oct 19, 2019
7073158
Don't ICE for completely unexpandable `impl Trait` types
matthewjasper Oct 20, 2019
0c05ed2
Apply suggestions from code review
matthewjasper Oct 25, 2019
9f257dd
Renamed ui/dead-code-ret to ui/unreachable-code-ret
Quantumplation Oct 25, 2019
cb5fd4e
Move dead_code related tests to test/ui/dead-code
Quantumplation Oct 25, 2019
402a8af
Remove lint callback from driver
Mark-Simulacrum Oct 25, 2019
8f988bd
Coherence should allow fundamental types to impl traits
ohadravid Oct 23, 2019
94890d2
Use ident instead of def_span in dead-code pass
Quantumplation Oct 25, 2019
b57f7f5
Rollup merge of #65541 - eddyb:spanned-inferred-outlives, r=nikomatsakis
Centril Oct 26, 2019
8b8e015
Rollup merge of #65566 - estebank:let-expr-as-ty, r=Centril
Centril Oct 26, 2019
3cf7f5a
Rollup merge of #65738 - ohadravid:re-rebalance-coherence-allow-funda…
Centril Oct 26, 2019
0498da3
Rollup merge of #65777 - matthewjasper:allow-impl-trait-expansion, r=…
Centril Oct 26, 2019
0cd12d3
Rollup merge of #65830 - Quantumplation:master, r=davidtwco
Centril Oct 26, 2019
c9d17b1
Rollup merge of #65834 - Mark-Simulacrum:driver-clean, r=nikomatsakis
Centril Oct 26, 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
2 changes: 1 addition & 1 deletion src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ rustc_queries! {

/// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
query inferred_outlives_of(_: DefId) -> &'tcx [ty::Predicate<'tcx>] {}
query inferred_outlives_of(_: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] {}

/// Maps from the `DefId` of a trait to the list of
/// super-predicates. This is a subset of the full list of
Expand Down
14 changes: 10 additions & 4 deletions src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,15 +378,21 @@ fn orphan_check_trait_ref<'tcx>(
// Let Ti be the first such type.
// - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
//
fn uncover_fundamental_ty(ty: Ty<'_>) -> Vec<Ty<'_>> {
if fundamental_ty(ty) {
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(ty)).collect()
fn uncover_fundamental_ty<'a>(
tcx: TyCtxt<'_>,
ty: Ty<'a>,
in_crate: InCrate,
) -> Vec<Ty<'a>> {
if fundamental_ty(ty) && !ty_is_local(tcx, ty, in_crate) {
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).collect()
} else {
vec![ty]
}
}

for input_ty in trait_ref.input_types().flat_map(uncover_fundamental_ty) {
for input_ty in
trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
{
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
if ty_is_local(tcx, input_ty, in_crate) {
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
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 @@ -1138,7 +1138,7 @@ pub struct CratePredicatesMap<'tcx> {
/// For each struct with outlive bounds, maps to a vector of the
/// predicate of its outlive bounds. If an item has no outlives
/// bounds, it will have no entry.
pub predicates: FxHashMap<DefId, &'tcx [ty::Predicate<'tcx>]>,
pub predicates: FxHashMap<DefId, &'tcx [(ty::Predicate<'tcx>, Span)]>,
}

impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
pub trait Callbacks {
/// Called before creating the compiler instance
fn config(&mut self, _config: &mut interface::Config) {}
/// Called early during compilation to allow other drivers to easily register lints.
fn extra_lints(&mut self, _ls: &mut lint::LintStore) {}
/// Called after parsing. Return value instructs the compiler whether to
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1497,10 +1497,10 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN

impl ExplicitOutlivesRequirements {
fn lifetimes_outliving_lifetime<'tcx>(
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
index: u32,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives.iter().filter_map(|pred| {
inferred_outlives.iter().filter_map(|(pred, _)| {
match pred {
ty::Predicate::RegionOutlives(outlives) => {
let outlives = outlives.skip_binder();
Expand All @@ -1517,10 +1517,10 @@ impl ExplicitOutlivesRequirements {
}

fn lifetimes_outliving_type<'tcx>(
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
index: u32,
) -> Vec<ty::Region<'tcx>> {
inferred_outlives.iter().filter_map(|pred| {
inferred_outlives.iter().filter_map(|(pred, _)| {
match pred {
ty::Predicate::TypeOutlives(outlives) => {
let outlives = outlives.skip_binder();
Expand All @@ -1539,7 +1539,7 @@ impl ExplicitOutlivesRequirements {
&self,
param: &'tcx hir::GenericParam,
tcx: TyCtxt<'tcx>,
inferred_outlives: &'tcx [ty::Predicate<'tcx>],
inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
ty_generics: &'tcx ty::Generics,
) -> Vec<ty::Region<'tcx>> {
let index = ty_generics.param_def_id_to_index[
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
return TAG_INVALID_SPAN.encode(self)
}

// HACK(eddyb) there's no way to indicate which crate a Span is coming
// from right now, so decoding would fail to find the SourceFile if
// it's not local to the crate the Span is found in.
if self.source_file_cache.is_imported() {
return TAG_INVALID_SPAN.encode(self)
}

TAG_VALID_SPAN.encode(self)?;
span.lo.encode(self)?;

Expand Down Expand Up @@ -379,6 +386,7 @@ impl<'tcx> EncodeContext<'tcx> {
.filter(|source_file| {
// No need to re-export imported source_files, as any downstream
// crate will import them from their original source.
// FIXME(eddyb) the `Span` encoding should take that into account.
!source_file.is_imported()
})
.map(|source_file| {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_passes/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) |
hir::ItemKind::Trait(..) |
hir::ItemKind::Impl(..) => self.tcx.sess.source_map().def_span(item.span),
hir::ItemKind::Impl(..) => item.ident.span,
_ => item.span,
};
let participle = match item.kind {
Expand Down
94 changes: 58 additions & 36 deletions src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,22 +316,8 @@ impl<'a> PathSource<'a> {
}
}

struct LateResolutionVisitor<'a, 'b> {
r: &'b mut Resolver<'a>,

/// The module that represents the current item scope.
parent_scope: ParentScope<'a>,

/// The current set of local scopes for types and values.
/// FIXME #4948: Reuse ribs to avoid allocation.
ribs: PerNS<Vec<Rib<'a>>>,

/// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a, NodeId>>,

/// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>,

#[derive(Default)]
struct DiagnosticMetadata {
/// The current trait's associated types' ident, used for diagnostic suggestions.
current_trait_assoc_types: Vec<Ident>,

Expand All @@ -350,6 +336,29 @@ struct LateResolutionVisitor<'a, 'b> {

/// Only used for better errors on `fn(): fn()`.
current_type_ascription: Vec<Span>,

/// Only used for better errors on `let <pat>: <expr, not type>;`.
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
}

struct LateResolutionVisitor<'a, 'b> {
r: &'b mut Resolver<'a>,

/// The module that represents the current item scope.
parent_scope: ParentScope<'a>,

/// The current set of local scopes for types and values.
/// FIXME #4948: Reuse ribs to avoid allocation.
ribs: PerNS<Vec<Rib<'a>>>,

/// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a, NodeId>>,

/// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>,

/// Fields used to add information to diagnostic errors.
diagnostic_metadata: DiagnosticMetadata,
}

/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
Expand All @@ -373,7 +382,18 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
self.resolve_expr(expr, None);
}
fn visit_local(&mut self, local: &'tcx Local) {
let local_spans = match local.pat.kind {
// We check for this to avoid tuple struct fields.
PatKind::Wild => None,
_ => Some((
local.pat.span,
local.ty.as_ref().map(|ty| ty.span),
local.init.as_ref().map(|init| init.span),
)),
};
let original = replace(&mut self.diagnostic_metadata.current_let_binding, local_spans);
self.resolve_local(local);
self.diagnostic_metadata.current_let_binding = original;
}
fn visit_ty(&mut self, ty: &'tcx Ty) {
match ty.kind {
Expand Down Expand Up @@ -415,7 +435,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
}
}
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, sp: Span, _: NodeId) {
let previous_value = replace(&mut self.current_function, Some(sp));
let previous_value = replace(&mut self.diagnostic_metadata.current_function, Some(sp));
debug!("(resolving function) entering function");
let rib_kind = match fn_kind {
FnKind::ItemFn(..) => FnItemRibKind,
Expand All @@ -441,7 +461,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
debug!("(resolving function) leaving function");
})
});
self.current_function = previous_value;
self.diagnostic_metadata.current_function = previous_value;
}

fn visit_generics(&mut self, generics: &'tcx Generics) {
Expand Down Expand Up @@ -475,7 +495,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
// (We however cannot ban `Self` for defaults on *all* generic
// lists; e.g. trait generics can usefully refer to `Self`,
// such as in the case of `trait Add<Rhs = Self>`.)
if self.current_self_item.is_some() { // (`Some` if + only if we are in ADT's generics.)
if self.diagnostic_metadata.current_self_item.is_some() {
// (`Some` if + only if we are in ADT's generics.)
default_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
}

Expand Down Expand Up @@ -527,12 +548,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
},
label_ribs: Vec::new(),
current_trait_ref: None,
current_trait_assoc_types: Vec::new(),
current_self_type: None,
current_self_item: None,
current_function: None,
unused_labels: Default::default(),
current_type_ascription: Vec::new(),
diagnostic_metadata: DiagnosticMetadata::default(),
}
}

Expand Down Expand Up @@ -892,16 +908,22 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {

fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
// Handle nested impls (inside fn bodies)
let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
let previous_value = replace(
&mut self.diagnostic_metadata.current_self_type,
Some(self_type.clone()),
);
let result = f(self);
self.current_self_type = previous_value;
self.diagnostic_metadata.current_self_type = previous_value;
result
}

fn with_current_self_item<T>(&mut self, self_item: &Item, f: impl FnOnce(&mut Self) -> T) -> T {
let previous_value = replace(&mut self.current_self_item, Some(self_item.id));
let previous_value = replace(
&mut self.diagnostic_metadata.current_self_item,
Some(self_item.id),
);
let result = f(self);
self.current_self_item = previous_value;
self.diagnostic_metadata.current_self_item = previous_value;
result
}

Expand All @@ -912,14 +934,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
f: impl FnOnce(&mut Self) -> T,
) -> T {
let trait_assoc_types = replace(
&mut self.current_trait_assoc_types,
&mut self.diagnostic_metadata.current_trait_assoc_types,
trait_items.iter().filter_map(|item| match &item.kind {
TraitItemKind::Type(bounds, _) if bounds.len() == 0 => Some(item.ident),
_ => None,
}).collect(),
);
let result = f(self);
self.current_trait_assoc_types = trait_assoc_types;
self.diagnostic_metadata.current_trait_assoc_types = trait_assoc_types;
result
}

Expand Down Expand Up @@ -1746,7 +1768,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {

fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
if let Some(label) = label {
self.unused_labels.insert(id, label.ident.span);
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
self.with_label_rib(NormalRibKind, |this| {
let ident = label.ident.modern_and_legacy();
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
Expand Down Expand Up @@ -1850,7 +1872,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
Some(node_id) => {
// Since this res is a label, it is never read.
self.r.label_res_map.insert(expr.id, node_id);
self.unused_labels.remove(&node_id);
self.diagnostic_metadata.unused_labels.remove(&node_id);
}
}

Expand Down Expand Up @@ -1912,9 +1934,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
}
}
ExprKind::Type(ref type_expr, _) => {
self.current_type_ascription.push(type_expr.span);
self.diagnostic_metadata.current_type_ascription.push(type_expr.span);
visit::walk_expr(self, expr);
self.current_type_ascription.pop();
self.diagnostic_metadata.current_type_ascription.pop();
}
// `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
// resolve the arguments within the proper scopes so that usages of them inside the
Expand Down Expand Up @@ -2073,7 +2095,7 @@ impl<'a> Resolver<'a> {
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
let mut late_resolution_visitor = LateResolutionVisitor::new(self);
visit::walk_crate(&mut late_resolution_visitor, krate);
for (id, span) in late_resolution_visitor.unused_labels.iter() {
for (id, span) in late_resolution_visitor.diagnostic_metadata.unused_labels.iter() {
self.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label");
}
}
Expand Down
Loading