Skip to content

Commit

Permalink
Auto merge of rust-lang#109015 - matthiaskrgr:rollup-xu2s31g, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#106276 (Fix `vec_deque::Drain` FIXME)
 - rust-lang#107629 (rustdoc: sort deprecated items lower in search)
 - rust-lang#108711 (Add note when matching token with nonterminal)
 - rust-lang#108757 (rustdoc: Migrate `document_item_info` to Askama)
 - rust-lang#108784 (rustdoc: Migrate sidebar rendering to Askama)
 - rust-lang#108927 (Move __thread_local_inner to sys)
 - rust-lang#108949 (Honor current target when checking conditional compilation values)
 - rust-lang#108950 (Directly construct Inherited in typeck.)
 - rust-lang#108988 (rustdoc: Don't crash on `crate` references in blocks)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 11, 2023
2 parents e350fe4 + e12ba73 commit 67e1681
Show file tree
Hide file tree
Showing 36 changed files with 1,728 additions and 1,544 deletions.
12 changes: 9 additions & 3 deletions compiler/rustc_expand/src/mbe/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
use std::borrow::Cow;

use crate::base::{DummyResult, ExtCtxt, MacResult};
use crate::expand::{parse_ast_fragment, AstFragmentKind};
use crate::mbe::{
macro_parser::{MatcherLoc, NamedParseResult, ParseResult::*, TtParser},
macro_rules::{try_match_macro, Tracker},
};
use rustc_ast::token::{self, Token};
use rustc_ast::token::{self, Token, TokenKind};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage};
use rustc_parse::parser::{Parser, Recovery};
use rustc_span::source_map::SourceMap;
use rustc_span::symbol::Ident;
use rustc_span::Span;
use std::borrow::Cow;

use super::macro_rules::{parser_from_cx, NoopTracker};

Expand Down Expand Up @@ -63,6 +62,13 @@ pub(super) fn failed_to_match_macro<'cx>(
err.note(format!("while trying to match {remaining_matcher}"));
}

if let MatcherLoc::Token { token: expected_token } = &remaining_matcher
&& (matches!(expected_token.kind, TokenKind::Interpolated(_))
|| matches!(token.kind, TokenKind::Interpolated(_)))
{
err.note("captured metavariables except for `$tt`, `$ident` and `$lifetime` cannot be compared to other tokens");
}

// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
if let Some((arg, comma_span)) = arg.add_comma() {
for lhs in lhses {
Expand Down
39 changes: 7 additions & 32 deletions compiler/rustc_hir_typeck/src/inherited.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirIdMap;
use rustc_infer::infer;
use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
Expand Down Expand Up @@ -73,40 +72,16 @@ impl<'tcx> Deref for Inherited<'tcx> {
}
}

/// A temporary returned by `Inherited::build(...)`. This is necessary
/// for multiple `InferCtxt` to share the same `typeck_results`
/// without using `Rc` or something similar.
pub struct InheritedBuilder<'tcx> {
infcx: infer::InferCtxtBuilder<'tcx>,
typeck_results: RefCell<ty::TypeckResults<'tcx>>,
}

impl<'tcx> Inherited<'tcx> {
pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner;

InheritedBuilder {
infcx: tcx
.infer_ctxt()
.ignoring_regions()
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
}
}
}

impl<'tcx> InheritedBuilder<'tcx> {
pub fn enter<F, R>(mut self, f: F) -> R
where
F: FnOnce(&Inherited<'tcx>) -> R,
{
f(&Inherited::new(self.infcx.build(), self.typeck_results))
}
}

impl<'tcx> Inherited<'tcx> {
fn new(infcx: InferCtxt<'tcx>, typeck_results: RefCell<ty::TypeckResults<'tcx>>) -> Self {
let tcx = infcx.tcx;
let infcx = tcx
.infer_ctxt()
.ignoring_regions()
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
.build();
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));

Inherited {
typeck_results,
Expand Down
234 changes: 115 additions & 119 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ mod rvalue_scopes;
mod upvar;
mod writeback;

pub use diverges::Diverges;
pub use expectation::Expectation;
pub use fn_ctxt::*;
pub use inherited::{Inherited, InheritedBuilder};
pub use fn_ctxt::FnCtxt;
pub use inherited::Inherited;

use crate::check::check_fn;
use crate::coercion::DynamicCoerceMany;
use crate::diverges::Diverges;
use crate::expectation::Expectation;
use crate::fn_ctxt::RawTy;
use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{
Expand Down Expand Up @@ -105,10 +106,9 @@ pub struct LocalTy<'tcx> {
/// (notably closures), `typeck_results(def_id)` would wind up
/// redirecting to the owning function.
fn primary_body_of(
tcx: TyCtxt<'_>,
id: hir::HirId,
node: Node<'_>,
) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> {
match tcx.hir().get(id) {
match node {
Node::Item(item) => match item.kind {
hir::ItemKind::Const(ty, body) | hir::ItemKind::Static(ty, _, body) => {
Some((body, Some(ty), None))
Expand Down Expand Up @@ -142,8 +142,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}

if let Some(def_id) = def_id.as_local() {
let id = tcx.hir().local_def_id_to_hir_id(def_id);
primary_body_of(tcx, id).is_some()
primary_body_of(tcx.hir().get_by_def_id(def_id)).is_some()
} else {
false
}
Expand Down Expand Up @@ -198,143 +197,140 @@ fn typeck_with_fallback<'tcx>(
}

let id = tcx.hir().local_def_id_to_hir_id(def_id);
let node = tcx.hir().get(id);
let span = tcx.hir().span(id);

// Figure out what primary body this item has.
let (body_id, body_ty, fn_sig) = primary_body_of(tcx, id).unwrap_or_else(|| {
let (body_id, body_ty, fn_sig) = primary_body_of(node).unwrap_or_else(|| {
span_bug!(span, "can't type-check body of {:?}", def_id);
});
let body = tcx.hir().body(body_id);

let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
let param_env = tcx.param_env(def_id);
let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
param_env.without_const()
let param_env = tcx.param_env(def_id);
let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
param_env.without_const()
} else {
param_env
};
let inh = Inherited::new(tcx, def_id);
let mut fcx = FnCtxt::new(&inh, param_env, def_id);

if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
} else {
param_env
tcx.fn_sig(def_id).subst_identity()
};
let mut fcx = FnCtxt::new(&inh, param_env, def_id);

if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None)
} else {
tcx.fn_sig(def_id).subst_identity()
};

check_abi(tcx, id, span, fn_sig.abi());
check_abi(tcx, id, span, fn_sig.abi());

// Compute the function signature from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
let fn_sig = fcx.normalize(body.value.span, fn_sig);
// Compute the function signature from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
let fn_sig = fcx.normalize(body.value.span, fn_sig);

check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
} else {
let expected_type = body_ty
.and_then(|ty| match ty.kind {
hir::TyKind::Infer => Some(fcx.astconv().ast_ty_to_ty(ty)),
_ => None,
})
.unwrap_or_else(|| match tcx.hir().get(id) {
Node::AnonConst(_) => match tcx.hir().get(tcx.hir().parent_id(id)) {
Node::Expr(&hir::Expr {
kind: hir::ExprKind::ConstBlock(ref anon_const),
..
}) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}),
Node::Ty(&hir::Ty {
kind: hir::TyKind::Typeof(ref anon_const), ..
}) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}),
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
let operand_ty =
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
if anon_const.hir_id == id =>
{
// Inline assembly constants must be integers.
Some(fcx.next_int_var())
}
hir::InlineAsmOperand::SymFn { anon_const }
if anon_const.hir_id == id =>
{
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
}))
}
_ => None,
});
operand_ty.unwrap_or_else(fallback)
check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
} else {
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
} else if let Node::AnonConst(_) = node {
match tcx.hir().get(tcx.hir().parent_id(id)) {
Node::Expr(&hir::Expr {
kind: hir::ExprKind::ConstBlock(ref anon_const), ..
}) if anon_const.hir_id == id => Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
})),
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
if anon_const.hir_id == id =>
{
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::TypeInference,
span,
}))
}
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
// Inline assembly constants must be integers.
Some(fcx.next_int_var())
}
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
Some(fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
}))
}
_ => fallback(),
},
_ => fallback(),
});
_ => None,
})
}
_ => None,
}
} else {
None
};
let expected_type = expected_type.unwrap_or_else(fallback);

let expected_type = fcx.normalize(body.value.span, expected_type);
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
let expected_type = fcx.normalize(body.value.span, expected_type);
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);

// Gather locals in statics (because of block expressions).
GatherLocalsVisitor::new(&fcx).visit_body(body);
// Gather locals in statics (because of block expressions).
GatherLocalsVisitor::new(&fcx).visit_body(body);

fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
fcx.check_expr_coercable_to_type(&body.value, expected_type, None);

fcx.write_ty(id, expected_type);
};
fcx.write_ty(id, expected_type);
};

fcx.type_inference_fallback();

// Even though coercion casts provide type hints, we check casts after fallback for
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
fcx.check_casts();
fcx.select_obligations_where_possible(|_| {});

// Closure and generator analysis may run after fallback
// because they don't constrain other type variables.
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
let prev_constness = fcx.param_env.constness();
fcx.param_env = fcx.param_env.without_const();
fcx.closure_analyze(body);
fcx.param_env = fcx.param_env.with_constness(prev_constness);
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
// Before the generator analysis, temporary scopes shall be marked to provide more
// precise information on types to be captured.
fcx.resolve_rvalue_scopes(def_id.to_def_id());

for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
let ty = fcx.normalize(span, ty);
fcx.require_type_is_sized(ty, span, code);
}
fcx.type_inference_fallback();

// Even though coercion casts provide type hints, we check casts after fallback for
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
fcx.check_casts();
fcx.select_obligations_where_possible(|_| {});

// Closure and generator analysis may run after fallback
// because they don't constrain other type variables.
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
let prev_constness = fcx.param_env.constness();
fcx.param_env = fcx.param_env.without_const();
fcx.closure_analyze(body);
fcx.param_env = fcx.param_env.with_constness(prev_constness);
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
// Before the generator analysis, temporary scopes shall be marked to provide more
// precise information on types to be captured.
fcx.resolve_rvalue_scopes(def_id.to_def_id());

for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
let ty = fcx.normalize(span, ty);
fcx.require_type_is_sized(ty, span, code);
}

fcx.select_obligations_where_possible(|_| {});
fcx.select_obligations_where_possible(|_| {});

debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());

// This must be the last thing before `report_ambiguity_errors`.
fcx.resolve_generator_interiors(def_id.to_def_id());
// This must be the last thing before `report_ambiguity_errors`.
fcx.resolve_generator_interiors(def_id.to_def_id());

debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());

if let None = fcx.infcx.tainted_by_errors() {
fcx.report_ambiguity_errors();
}
if let None = fcx.infcx.tainted_by_errors() {
fcx.report_ambiguity_errors();
}

if let None = fcx.infcx.tainted_by_errors() {
fcx.check_transmutes();
}
if let None = fcx.infcx.tainted_by_errors() {
fcx.check_transmutes();
}

fcx.check_asms();
fcx.check_asms();

fcx.infcx.skip_region_resolution();
fcx.infcx.skip_region_resolution();

fcx.resolve_type_vars_in_body(body)
});
let typeck_results = fcx.resolve_type_vars_in_body(body);

// Consistency check our TypeckResults instance can hold all ItemLocalIds
// it will need to hold.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub fn create_session(
add_configuration(&mut cfg, &mut sess, &*codegen_backend);

let mut check_cfg = config::to_crate_check_config(check_cfg);
check_cfg.fill_well_known();
check_cfg.fill_well_known(&sess.target);

sess.parse_sess.config = cfg;
sess.parse_sess.check_config = check_cfg;
Expand Down
Loading

0 comments on commit 67e1681

Please sign in to comment.