Skip to content

Commit

Permalink
Auto merge of #80566 - Dylan-DPC:rollup-rns6est, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #80323 (Update and improve `rustc_codegen_{llvm,ssa}` docs)
 - #80368 (rustdoc: Render visibilities succinctly)
 - #80514 (Fix broken ./x.py install)
 - #80519 (Take type defaults into account in suggestions to reorder generic parameters)
 - #80526 (Update LLVM)
 - #80532 (remove unnecessary trailing semicolon from bootstrap)
 - #80548 (FIx ICE on wf check for foreign fns)
 - #80551 (support pattern as const parents in type_of)

Failed merges:

 - #80547 (In which we start to parse const generics defaults)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 1, 2021
2 parents 44e3daf + 96c11f9 commit 99ad5a1
Show file tree
Hide file tree
Showing 34 changed files with 487 additions and 307 deletions.
56 changes: 31 additions & 25 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,35 +717,46 @@ impl<'a> AstValidator<'a> {

/// Checks that generic parameters are in the correct order,
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
fn validate_generic_param_order<'a>(
fn validate_generic_param_order(
sess: &Session,
handler: &rustc_errors::Handler,
generics: impl Iterator<Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option<String>)>,
generics: &[GenericParam],
span: Span,
) {
let mut max_param: Option<ParamKindOrd> = None;
let mut out_of_order = FxHashMap::default();
let mut param_idents = vec![];

for (kind, bounds, span, ident) in generics {
for param in generics {
let ident = Some(param.ident.to_string());
let (kind, bounds, span) = (&param.kind, Some(&*param.bounds), param.ident.span);
let (ord_kind, ident) = match &param.kind {
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
GenericParamKind::Const { ref ty, kw_span: _ } => {
let ty = pprust::ty_to_string(ty);
let unordered = sess.features_untracked().const_generics;
(ParamKindOrd::Const { unordered }, Some(format!("const {}: {}", param.ident, ty)))
}
};
if let Some(ident) = ident {
param_idents.push((kind, bounds, param_idents.len(), ident));
param_idents.push((kind, ord_kind, bounds, param_idents.len(), ident));
}
let max_param = &mut max_param;
match max_param {
Some(max_param) if *max_param > kind => {
let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
Some(max_param) if *max_param > ord_kind => {
let entry = out_of_order.entry(ord_kind).or_insert((*max_param, vec![]));
entry.1.push(span);
}
Some(_) | None => *max_param = Some(kind),
Some(_) | None => *max_param = Some(ord_kind),
};
}

let mut ordered_params = "<".to_string();
if !out_of_order.is_empty() {
param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
param_idents.sort_by_key(|&(_, po, _, i, _)| (po, i));
let mut first = true;
for (_, bounds, _, ident) in param_idents {
for (kind, _, bounds, _, ident) in param_idents {
if !first {
ordered_params += ", ";
}
Expand All @@ -756,6 +767,16 @@ fn validate_generic_param_order<'a>(
ordered_params += &pprust::bounds_to_string(&bounds);
}
}
match kind {
GenericParamKind::Type { default: Some(default) } => {
ordered_params += " = ";
ordered_params += &pprust::ty_to_string(default);
}
GenericParamKind::Type { default: None } => (),
GenericParamKind::Lifetime => (),
// FIXME(const_generics:defaults)
GenericParamKind::Const { ty: _, kw_span: _ } => (),
}
first = false;
}
}
Expand Down Expand Up @@ -1150,22 +1171,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
validate_generic_param_order(
self.session,
self.err_handler(),
generics.params.iter().map(|param| {
let ident = Some(param.ident.to_string());
let (kind, ident) = match &param.kind {
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
GenericParamKind::Const { ref ty, kw_span: _ } => {
let ty = pprust::ty_to_string(ty);
let unordered = self.session.features_untracked().const_generics;
(
ParamKindOrd::Const { unordered },
Some(format!("const {}: {}", param.ident, ty)),
)
}
};
(kind, Some(&*param.bounds), param.ident.span, ident)
}),
&generics.params,
generics.span,
);

Expand Down
18 changes: 8 additions & 10 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
//! Codegen the completed AST to the LLVM IR.
//!
//! Some functions here, such as codegen_block and codegen_expr, return a value --
//! the result of the codegen to LLVM -- while others, such as codegen_fn
//! and mono_item, are called only for the side effect of adding a
//! particular definition to the LLVM IR output we're producing.
//! Codegen the MIR to the LLVM IR.
//!
//! Hopefully useful general knowledge about codegen:
//!
//! * There's no way to find out the `Ty` type of a Value. Doing so
//! * There's no way to find out the [`Ty`] type of a [`Value`]. Doing so
//! would be "trying to get the eggs out of an omelette" (credit:
//! pcwalton). You can, instead, find out its `llvm::Type` by calling `val_ty`,
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
//! pcwalton). You can, instead, find out its [`llvm::Type`] by calling [`val_ty`],
//! but one [`llvm::Type`] corresponds to many [`Ty`]s; for instance, `tup(int, int,
//! int)` and `rec(x=int, y=int, z=int)` will have the same [`llvm::Type`].
//!
//! [`Ty`]: rustc_middle::ty::Ty
//! [`val_ty`]: common::val_ty

use super::ModuleLlvm;

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}

/// Get the [LLVM type][Type] of a [`Value`].
pub fn val_ty(v: &Value) -> &Type {
unsafe { llvm::LLVMTypeOf(v) }
}
Expand Down
15 changes: 0 additions & 15 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
//! Codegen the completed AST to the LLVM IR.
//!
//! Some functions here, such as `codegen_block` and `codegen_expr`, return a value --
//! the result of the codegen to LLVM -- while others, such as `codegen_fn`
//! and `mono_item`, are called only for the side effect of adding a
//! particular definition to the LLVM IR output we're producing.
//!
//! Hopefully useful general knowledge about codegen:
//!
//! * There's no way to find out the `Ty` type of a `Value`. Doing so
//! would be "trying to get the eggs out of an omelette" (credit:
//! pcwalton). You can, instead, find out its `llvm::Type` by calling `val_ty`,
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.

use crate::back::write::{
compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm,
submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen,
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,9 +760,9 @@ pub struct Pat<'hir> {
pub default_binding_modes: bool,
}

impl Pat<'_> {
impl<'hir> Pat<'hir> {
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) -> bool {
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
if !it(self) {
return false;
}
Expand All @@ -785,12 +785,12 @@ impl Pat<'_> {
/// Note that when visiting e.g. `Tuple(ps)`,
/// if visiting `ps[0]` returns `false`,
/// then `ps[1]` will not be visited.
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'_>) -> bool) -> bool {
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
self.walk_short_(&mut it)
}

// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) {
fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
if !it(self) {
return;
}
Expand All @@ -810,7 +810,7 @@ impl Pat<'_> {
/// Walk the pattern in left-to-right order.
///
/// If `it(pat)` returns `false`, the children are not visited.
pub fn walk(&self, mut it: impl FnMut(&Pat<'_>) -> bool) {
pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
self.walk_(&mut it)
}

Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ fn msg_span_from_early_bound_and_free_regions(
Some(Node::Item(it)) => item_scope_tag(&it),
Some(Node::TraitItem(it)) => trait_item_scope_tag(&it),
Some(Node::ImplItem(it)) => impl_item_scope_tag(&it),
Some(Node::ForeignItem(it)) => foreign_item_scope_tag(&it),
_ => unreachable!(),
};
let (prefix, span) = match *region {
Expand Down Expand Up @@ -233,6 +234,13 @@ fn impl_item_scope_tag(item: &hir::ImplItem<'_>) -> &'static str {
}
}

fn foreign_item_scope_tag(item: &hir::ForeignItem<'_>) -> &'static str {
match item.kind {
hir::ForeignItemKind::Fn(..) => "method body",
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => "associated item",
}
}

fn explain_span(tcx: TyCtxt<'tcx>, heading: &str, span: Span) -> (String, Option<Span>) {
let lo = tcx.sess.source_map().lookup_char_pos(span.lo());
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), Some(span))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
let fcx = FnCtxt::new(&inh, param_env, id);
if !inh.tcx.features().trivial_bounds {
// As predicates are cached rather than obligations, this
// needsto be called first so that they are checked with an
// needs to be called first so that they are checked with an
// empty `param_env`.
check_false_global_bounds(&fcx, span, id);
}
Expand Down
52 changes: 46 additions & 6 deletions compiler/rustc_typeck/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor;
use rustc_hir::Node;
use rustc_hir::{HirId, Node};
use rustc_middle::hir::map::Map;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
use rustc_middle::ty::util::IntTypeExt;
Expand All @@ -22,7 +22,6 @@ use super::{bad_placeholder_type, is_suggestable_infer_ty};
/// This should be called using the query `tcx.opt_const_param_of`.
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
use hir::*;

let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

if let Node::AnonConst(_) = tcx.hir().get(hir_id) {
Expand Down Expand Up @@ -62,9 +61,9 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
}

Node::Ty(&Ty { kind: TyKind::Path(_), .. })
| Node::Expr(&Expr { kind: ExprKind::Struct(..), .. })
| Node::Expr(&Expr { kind: ExprKind::Path(_), .. })
| Node::TraitRef(..) => {
| Node::Expr(&Expr { kind: ExprKind::Path(_) | ExprKind::Struct(..), .. })
| Node::TraitRef(..)
| Node::Pat(_) => {
let path = match parent_node {
Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. })
| Node::TraitRef(&TraitRef { path, .. }) => &*path,
Expand All @@ -79,6 +78,20 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
let _tables = tcx.typeck(body_owner);
&*path
}
Node::Pat(pat) => {
if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
path
} else {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
&format!(
"unable to find const parent for {} in pat {:?}",
hir_id, pat
),
);
return None;
}
}
_ => {
tcx.sess.delay_span_bug(
tcx.def_span(def_id),
Expand All @@ -91,7 +104,6 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// We've encountered an `AnonConst` in some path, so we need to
// figure out which generic parameter it corresponds to and return
// the relevant type.

let (arg_index, segment) = path
.segments
.iter()
Expand Down Expand Up @@ -144,6 +156,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
}
}

fn get_path_containing_arg_in_pat<'hir>(
pat: &'hir hir::Pat<'hir>,
arg_id: HirId,
) -> Option<&'hir hir::Path<'hir>> {
use hir::*;

let is_arg_in_path = |p: &hir::Path<'_>| {
p.segments
.iter()
.filter_map(|seg| seg.args)
.flat_map(|args| args.args)
.any(|arg| arg.id() == arg_id)
};
let mut arg_path = None;
pat.walk(|pat| match pat.kind {
PatKind::Struct(QPath::Resolved(_, path), _, _)
| PatKind::TupleStruct(QPath::Resolved(_, path), _, _)
| PatKind::Path(QPath::Resolved(_, path))
if is_arg_in_path(path) =>
{
arg_path = Some(path);
false
}
_ => true,
});
arg_path
}

pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
let def_id = def_id.expect_local();
use rustc_hir::*;
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ impl Merge for TomlConfig {
*x = Some(new);
}
}
};
}
do_merge(&mut self.build, build);
do_merge(&mut self.install, install);
do_merge(&mut self.llvm, llvm);
Expand Down
Loading

0 comments on commit 99ad5a1

Please sign in to comment.