Auto merge of #92627 - matthiaskrgr:rollup-xmz0rib, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #91055 (return the correct type for closures in `type_of`) - #92207 (Delay remaining `span_bug`s in drop elaboration) - #92417 (Fix spacing and ordering of words in pretty printed Impl) - #92504 (Exit nonzero on rustc -Wall) - #92559 (RustWrapper: adapt to new AttributeMask API) - #92589 (Break the loop) - #92607 (rustc_metadata: Some minor cleanups and optimizations) - #92620 (Remove unused `ExtendDefault` struct) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e012a191d7
22 changed files with 215 additions and 141 deletions
|
@ -1287,14 +1287,17 @@ impl<'a> State<'a> {
|
|||
self.print_visibility(&item.vis);
|
||||
self.print_defaultness(defaultness);
|
||||
self.print_unsafety(unsafety);
|
||||
self.word_nbsp("impl");
|
||||
self.print_constness(constness);
|
||||
self.word("impl");
|
||||
|
||||
if !generics.params.is_empty() {
|
||||
if generics.params.is_empty() {
|
||||
self.nbsp();
|
||||
} else {
|
||||
self.print_generic_params(&generics.params);
|
||||
self.space();
|
||||
}
|
||||
|
||||
self.print_constness(constness);
|
||||
|
||||
if let ast::ImplPolarity::Negative(_) = polarity {
|
||||
self.word("!");
|
||||
}
|
||||
|
|
|
@ -1040,7 +1040,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
|||
let wall = matches.opt_strs("W");
|
||||
if wall.iter().any(|x| *x == "all") {
|
||||
print_wall_help();
|
||||
return None;
|
||||
rustc_errors::FatalError.raise();
|
||||
}
|
||||
|
||||
// Don't handle -W help here, because we might first load plugins.
|
||||
|
|
|
@ -341,14 +341,12 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
|
|||
unsigned Index,
|
||||
LLVMRustAttribute RustAttr) {
|
||||
Function *F = unwrap<Function>(Fn);
|
||||
Attribute Attr = Attribute::get(F->getContext(), fromRust(RustAttr));
|
||||
AttrBuilder B(Attr);
|
||||
auto PAL = F->getAttributes();
|
||||
AttributeList PAL = F->getAttributes();
|
||||
AttributeList PALNew;
|
||||
#if LLVM_VERSION_LT(14, 0)
|
||||
PALNew = PAL.removeAttributes(F->getContext(), Index, B);
|
||||
PALNew = PAL.removeAttribute(F->getContext(), Index, fromRust(RustAttr));
|
||||
#else
|
||||
PALNew = PAL.removeAttributesAtIndex(F->getContext(), Index, B);
|
||||
PALNew = PAL.removeAttributeAtIndex(F->getContext(), Index, fromRust(RustAttr));
|
||||
#endif
|
||||
F->setAttributes(PALNew);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
|
|||
use rustc_middle::mir::{self, Body, Promoted};
|
||||
use rustc_middle::thir;
|
||||
use rustc_middle::ty::codec::TyDecoder;
|
||||
use rustc_middle::ty::fast_reject::SimplifiedType;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
|
||||
use rustc_serialize::{opaque, Decodable, Decoder};
|
||||
use rustc_session::cstore::{
|
||||
|
@ -92,8 +93,7 @@ crate struct CrateMetadata {
|
|||
/// Trait impl data.
|
||||
/// FIXME: Used only from queries and can use query cache,
|
||||
/// so pre-decoding can probably be avoided.
|
||||
trait_impls:
|
||||
FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>>,
|
||||
trait_impls: FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<SimplifiedType>)]>>,
|
||||
/// Proc macro descriptions for this crate, if it's a proc macro crate.
|
||||
raw_proc_macros: Option<&'static [ProcMacro]>,
|
||||
/// Source maps for code from the crate.
|
||||
|
@ -722,25 +722,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
&self.raw_proc_macros.unwrap()[pos]
|
||||
}
|
||||
|
||||
fn try_item_ident(&self, item_index: DefIndex, sess: &Session) -> Result<Ident, String> {
|
||||
let name = self
|
||||
.def_key(item_index)
|
||||
.disambiguated_data
|
||||
.data
|
||||
.get_opt_name()
|
||||
.ok_or_else(|| format!("Missing opt name for {:?}", item_index))?;
|
||||
let span = self
|
||||
.root
|
||||
.tables
|
||||
.ident_span
|
||||
.get(self, item_index)
|
||||
.ok_or_else(|| format!("Missing ident span for {:?} ({:?})", name, item_index))?
|
||||
.decode((self, sess));
|
||||
Ok(Ident::new(name, span))
|
||||
fn opt_item_ident(&self, item_index: DefIndex, sess: &Session) -> Option<Ident> {
|
||||
let name = self.def_key(item_index).disambiguated_data.data.get_opt_name()?;
|
||||
let span = match self.root.tables.ident_span.get(self, item_index) {
|
||||
Some(lazy_span) => lazy_span.decode((self, sess)),
|
||||
None => {
|
||||
// FIXME: this weird case of a name with no span is specific to `extern crate`
|
||||
// items, which are supposed to be treated like `use` items and only be encoded
|
||||
// to metadata as `Export`s, return `None` because that's what all the callers
|
||||
// expect in this case.
|
||||
assert_eq!(self.def_kind(item_index), DefKind::ExternCrate);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(Ident::new(name, span))
|
||||
}
|
||||
|
||||
fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident {
|
||||
self.try_item_ident(item_index, sess).unwrap()
|
||||
self.opt_item_ident(item_index, sess).expect("no encoded ident for item")
|
||||
}
|
||||
|
||||
fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
|
||||
|
@ -1102,27 +1101,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
// Iterate over all children.
|
||||
if let Some(children) = self.root.tables.children.get(self, id) {
|
||||
for child_index in children.decode((self, sess)) {
|
||||
// FIXME: Merge with the logic below.
|
||||
if let None | Some(EntryKind::ForeignMod | EntryKind::Impl(_)) =
|
||||
self.maybe_kind(child_index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let def_key = self.def_key(child_index);
|
||||
if def_key.disambiguated_data.data.get_opt_name().is_some() {
|
||||
let span = self.get_span(child_index, sess);
|
||||
if let Some(ident) = self.opt_item_ident(child_index, sess) {
|
||||
let kind = self.def_kind(child_index);
|
||||
let ident = self.item_ident(child_index, sess);
|
||||
let vis = self.get_visibility(child_index);
|
||||
let def_id = self.local_def_id(child_index);
|
||||
let res = Res::Def(kind, def_id);
|
||||
|
||||
if matches!(kind, DefKind::Macro(..)) {
|
||||
// FIXME: Macros are currently encoded twice, once as items and once as
|
||||
// reexports. We ignore the items here and only use the reexports.
|
||||
if !matches!(kind, DefKind::Macro(..)) {
|
||||
callback(Export { res, ident, vis, span });
|
||||
continue;
|
||||
}
|
||||
let def_id = self.local_def_id(child_index);
|
||||
let res = Res::Def(kind, def_id);
|
||||
let vis = self.get_visibility(child_index);
|
||||
let span = self.get_span(child_index, sess);
|
||||
|
||||
callback(Export { ident, res, vis, span });
|
||||
|
||||
// For non-re-export structs and variants add their constructors to children.
|
||||
// Re-export lists automatically contain constructors when necessary.
|
||||
|
@ -1309,24 +1300,26 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
|
||||
fn get_item_attrs(
|
||||
&'a self,
|
||||
node_id: DefIndex,
|
||||
id: DefIndex,
|
||||
sess: &'a Session,
|
||||
) -> impl Iterator<Item = ast::Attribute> + 'a {
|
||||
// The attributes for a tuple struct/variant are attached to the definition, not the ctor;
|
||||
// we assume that someone passing in a tuple struct ctor is actually wanting to
|
||||
// look at the definition
|
||||
let def_key = self.def_key(node_id);
|
||||
let item_id = if def_key.disambiguated_data.data == DefPathData::Ctor {
|
||||
def_key.parent.unwrap()
|
||||
} else {
|
||||
node_id
|
||||
};
|
||||
|
||||
self.root
|
||||
.tables
|
||||
.attributes
|
||||
.get(self, item_id)
|
||||
.unwrap_or_else(Lazy::empty)
|
||||
.get(self, id)
|
||||
.unwrap_or_else(|| {
|
||||
// Structure and variant constructors don't have any attributes encoded for them,
|
||||
// but we assume that someone passing a constructor ID actually wants to look at
|
||||
// the attributes on the corresponding struct or variant.
|
||||
let def_key = self.def_key(id);
|
||||
assert_eq!(def_key.disambiguated_data.data, DefPathData::Ctor);
|
||||
let parent_id = def_key.parent.expect("no parent for a constructor");
|
||||
self.root
|
||||
.tables
|
||||
.attributes
|
||||
.get(self, parent_id)
|
||||
.expect("no encoded attributes for a structure or variant")
|
||||
})
|
||||
.decode((self, sess))
|
||||
}
|
||||
|
||||
|
@ -1372,40 +1365,40 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
self.root.traits.decode(self).map(|index| self.local_def_id(index))
|
||||
}
|
||||
|
||||
fn get_implementations_for_trait(
|
||||
fn get_trait_impls(&'a self) -> impl Iterator<Item = (DefId, Option<SimplifiedType>)> + 'a {
|
||||
self.trait_impls.values().flat_map(move |impls| {
|
||||
impls
|
||||
.decode(self)
|
||||
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_implementations_of_trait(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
filter: Option<DefId>,
|
||||
) -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
|
||||
trait_def_id: DefId,
|
||||
) -> &'tcx [(DefId, Option<SimplifiedType>)] {
|
||||
if self.root.is_proc_macro_crate() {
|
||||
// proc-macro crates export no trait impls.
|
||||
return &[];
|
||||
}
|
||||
|
||||
if let Some(def_id) = filter {
|
||||
// Do a reverse lookup beforehand to avoid touching the crate_num
|
||||
// hash map in the loop below.
|
||||
let filter = match self.reverse_translate_def_id(def_id) {
|
||||
let key = match self.reverse_translate_def_id(trait_def_id) {
|
||||
Some(def_id) => (def_id.krate.as_u32(), def_id.index),
|
||||
None => return &[],
|
||||
};
|
||||
|
||||
if let Some(impls) = self.trait_impls.get(&filter) {
|
||||
if let Some(impls) = self.trait_impls.get(&key) {
|
||||
tcx.arena.alloc_from_iter(
|
||||
impls.decode(self).map(|(idx, simplified_self_ty)| {
|
||||
(self.local_def_id(idx), simplified_self_ty)
|
||||
}),
|
||||
impls
|
||||
.decode(self)
|
||||
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)),
|
||||
)
|
||||
} else {
|
||||
&[]
|
||||
}
|
||||
} else {
|
||||
tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| {
|
||||
impls
|
||||
.decode(self)
|
||||
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty))
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
|
||||
|
|
|
@ -133,9 +133,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
generator_kind => { cdata.generator_kind(def_id.index) }
|
||||
opt_def_kind => { Some(cdata.def_kind(def_id.index)) }
|
||||
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
|
||||
def_ident_span => {
|
||||
cdata.try_item_ident(def_id.index, &tcx.sess).ok().map(|ident| ident.span)
|
||||
}
|
||||
def_ident_span => { cdata.opt_item_ident(def_id.index, &tcx.sess).map(|ident| ident.span) }
|
||||
lookup_stability => {
|
||||
cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
|
||||
}
|
||||
|
@ -145,9 +143,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
lookup_deprecation_entry => {
|
||||
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
|
||||
}
|
||||
item_attrs => { tcx.arena.alloc_from_iter(
|
||||
cdata.get_item_attrs(def_id.index, tcx.sess)
|
||||
) }
|
||||
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
|
||||
fn_arg_names => { cdata.get_fn_param_names(tcx, def_id.index) }
|
||||
rendered_const => { cdata.get_rendered_const(def_id.index) }
|
||||
impl_parent => { cdata.get_parent_impl(def_id.index) }
|
||||
|
@ -196,14 +192,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
|
|||
extra_filename => { cdata.root.extra_filename.clone() }
|
||||
|
||||
traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
||||
all_trait_implementations => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }
|
||||
|
||||
implementations_of_trait => {
|
||||
cdata.get_implementations_for_trait(tcx, Some(other))
|
||||
}
|
||||
|
||||
all_trait_implementations => {
|
||||
cdata.get_implementations_for_trait(tcx, None)
|
||||
}
|
||||
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
|
||||
|
||||
visibility => { cdata.get_visibility(def_id.index) }
|
||||
dep_kind => {
|
||||
|
@ -470,7 +461,7 @@ impl CStore {
|
|||
self.get_crate_data(cnum).num_def_ids()
|
||||
}
|
||||
|
||||
pub fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
|
||||
pub fn item_attrs_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
|
||||
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ use rustc_middle::mir::interpret;
|
|||
use rustc_middle::thir;
|
||||
use rustc_middle::traits::specialization_graph;
|
||||
use rustc_middle::ty::codec::TyEncoder;
|
||||
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
|
||||
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
|
||||
use rustc_serialize::{opaque, Encodable, Encoder};
|
||||
|
@ -2055,7 +2055,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
|
||||
struct ImplsVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
impls: FxHashMap<DefId, Vec<(DefIndex, Option<fast_reject::SimplifiedType>)>>,
|
||||
impls: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>>,
|
||||
}
|
||||
|
||||
impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
|
||||
|
|
|
@ -16,6 +16,7 @@ use rustc_middle::hir::exports::Export;
|
|||
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::thir;
|
||||
use rustc_middle::ty::fast_reject::SimplifiedType;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, ReprOptions, Ty};
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
|
@ -261,7 +262,7 @@ crate struct CrateDep {
|
|||
#[derive(MetadataEncodable, MetadataDecodable)]
|
||||
crate struct TraitImpls {
|
||||
trait_id: (u32, DefIndex),
|
||||
impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>,
|
||||
impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
|
||||
}
|
||||
|
||||
/// Define `LazyTables` and `TableBuilders` at the same time.
|
||||
|
|
|
@ -1411,16 +1411,14 @@ rustc_queries! {
|
|||
|
||||
/// Given a crate and a trait, look up all impls of that trait in the crate.
|
||||
/// Return `(impl_id, self_ty)`.
|
||||
query implementations_of_trait(_: (CrateNum, DefId))
|
||||
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
|
||||
query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option<SimplifiedType>)] {
|
||||
desc { "looking up implementations of a trait in a crate" }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
/// Given a crate, look up all trait impls in that crate.
|
||||
/// Return `(impl_id, self_ty)`.
|
||||
query all_trait_implementations(_: CrateNum)
|
||||
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
|
||||
query all_trait_implementations(_: CrateNum) -> &'tcx [(DefId, Option<SimplifiedType>)] {
|
||||
desc { "looking up all (?) trait implementations" }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
|
|
@ -143,6 +143,18 @@ pub fn simplify_type(
|
|||
}
|
||||
|
||||
impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
|
||||
pub fn def(self) -> Option<D> {
|
||||
match self {
|
||||
AdtSimplifiedType(d)
|
||||
| ForeignSimplifiedType(d)
|
||||
| TraitSimplifiedType(d)
|
||||
| ClosureSimplifiedType(d)
|
||||
| GeneratorSimplifiedType(d)
|
||||
| OpaqueSimplifiedType(d) => Some(d),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U>
|
||||
where
|
||||
F: Fn(D) -> U,
|
||||
|
|
|
@ -28,6 +28,7 @@ use crate::traits::query::{
|
|||
};
|
||||
use crate::traits::specialization_graph;
|
||||
use crate::traits::{self, ImplSource};
|
||||
use crate::ty::fast_reject::SimplifiedType;
|
||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||
use crate::ty::util::AlwaysRequiresDrop;
|
||||
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::traits::specialization_graph;
|
||||
use crate::ty::fast_reject::{self, SimplifyParams, StripReferences};
|
||||
use crate::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
|
||||
use crate::ty::fold::TypeFoldable;
|
||||
use crate::ty::{Ty, TyCtxt};
|
||||
use rustc_hir as hir;
|
||||
|
@ -68,7 +68,7 @@ pub enum TraitSpecializationKind {
|
|||
pub struct TraitImpls {
|
||||
blanket_impls: Vec<DefId>,
|
||||
/// Impls indexed by their simplified self type, for fast lookup.
|
||||
non_blanket_impls: FxIndexMap<fast_reject::SimplifiedType, Vec<DefId>>,
|
||||
non_blanket_impls: FxIndexMap<SimplifiedType, Vec<DefId>>,
|
||||
}
|
||||
|
||||
impl TraitImpls {
|
||||
|
|
|
@ -316,12 +316,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
LookupResult::Parent(Some(parent)) => {
|
||||
let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent);
|
||||
if maybe_dead {
|
||||
span_bug!(
|
||||
self.tcx.sess.delay_span_bug(
|
||||
terminator.source_info.span,
|
||||
&format!(
|
||||
"drop of untracked, uninitialized value {:?}, place {:?} ({:?})",
|
||||
bb,
|
||||
place,
|
||||
path
|
||||
bb, place, path,
|
||||
),
|
||||
);
|
||||
}
|
||||
continue;
|
||||
|
@ -368,10 +368,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
bb,
|
||||
),
|
||||
LookupResult::Parent(..) => {
|
||||
span_bug!(
|
||||
self.tcx.sess.delay_span_bug(
|
||||
terminator.source_info.span,
|
||||
"drop of untracked value {:?}",
|
||||
bb
|
||||
&format!("drop of untracked value {:?}", bb),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -895,8 +895,11 @@ impl<'a> Resolver<'a> {
|
|||
// a note about editions
|
||||
let note = if let Some(did) = did {
|
||||
let requires_note = !did.is_local()
|
||||
&& this.cstore().item_attrs(did, this.session).iter().any(
|
||||
|attr| {
|
||||
&& this
|
||||
.cstore()
|
||||
.item_attrs_untracked(did, this.session)
|
||||
.iter()
|
||||
.any(|attr| {
|
||||
if attr.has_name(sym::rustc_diagnostic_item) {
|
||||
[sym::TryInto, sym::TryFrom, sym::FromIterator]
|
||||
.map(|x| Some(x))
|
||||
|
@ -904,8 +907,7 @@ impl<'a> Resolver<'a> {
|
|||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
requires_note.then(|| {
|
||||
format!(
|
||||
|
|
|
@ -3420,7 +3420,7 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
let attr = self
|
||||
.cstore()
|
||||
.item_attrs(def_id, self.session)
|
||||
.item_attrs_untracked(def_id, self.session)
|
||||
.into_iter()
|
||||
.find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
|
||||
let mut ret = Vec::new();
|
||||
|
|
|
@ -295,7 +295,9 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||
if let hir::ExprKind::Closure(..) = expr.kind {
|
||||
let def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||
self.tcx.ensure().generics_of(def_id);
|
||||
self.tcx.ensure().type_of(def_id);
|
||||
// We do not call `type_of` for closures here as that
|
||||
// depends on typecheck and would therefore hide
|
||||
// any further errors in case one typeck fails.
|
||||
}
|
||||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
|
|
|
@ -470,14 +470,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
|
||||
Node::Field(field) => icx.to_ty(field.ty),
|
||||
|
||||
Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||
if let Some(movability) = gen {
|
||||
tcx.mk_generator(def_id.to_def_id(), substs, movability)
|
||||
} else {
|
||||
tcx.mk_closure(def_id.to_def_id(), substs)
|
||||
}
|
||||
}
|
||||
Node::Expr(&Expr { kind: ExprKind::Closure(..), .. }) => tcx.typeck(def_id).node_type(hir_id),
|
||||
|
||||
Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
|
||||
// We defer to `type_of` of the corresponding parameter
|
||||
|
|
|
@ -715,13 +715,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
|||
|
||||
debug!("walk_captures({:?})", closure_expr);
|
||||
|
||||
let closure_def_id = self.tcx().hir().local_def_id(closure_expr.hir_id).to_def_id();
|
||||
let upvars = self.tcx().upvars_mentioned(self.body_owner);
|
||||
let tcx = self.tcx();
|
||||
let closure_def_id = tcx.hir().local_def_id(closure_expr.hir_id).to_def_id();
|
||||
let upvars = tcx.upvars_mentioned(self.body_owner);
|
||||
|
||||
// For purposes of this function, generator and closures are equivalent.
|
||||
let body_owner_is_closure = matches!(
|
||||
self.tcx().type_of(self.body_owner.to_def_id()).kind(),
|
||||
ty::Closure(..) | ty::Generator(..)
|
||||
tcx.hir().body_owner_kind(tcx.hir().local_def_id_to_hir_id(self.body_owner)),
|
||||
hir::BodyOwnerKind::Closure,
|
||||
);
|
||||
|
||||
// If we have a nested closure, we want to include the fake reads present in the nested closure.
|
||||
|
|
|
@ -2277,16 +2277,6 @@ impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
|
|||
}
|
||||
}
|
||||
|
||||
struct ExtendDefault;
|
||||
impl<T: Default> ExtendWith<T> for ExtendDefault {
|
||||
fn next(&mut self) -> T {
|
||||
Default::default()
|
||||
}
|
||||
fn last(self) -> T {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
struct ExtendFunc<F>(F);
|
||||
impl<T, F: FnMut() -> T> ExtendWith<T> for ExtendFunc<F> {
|
||||
fn next(&mut self) -> T {
|
||||
|
|
|
@ -13,7 +13,7 @@ import sys
|
|||
import tarfile
|
||||
import tempfile
|
||||
|
||||
from time import time
|
||||
from time import time, sleep
|
||||
|
||||
# Acquire a lock on the build directory to make sure that
|
||||
# we don't cause a race condition while building
|
||||
|
@ -42,8 +42,10 @@ def acquire_lock(build_dir):
|
|||
while True:
|
||||
try:
|
||||
curs.execute("BEGIN EXCLUSIVE")
|
||||
break
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
sleep(0.25)
|
||||
return curs
|
||||
except ImportError:
|
||||
print("warning: sqlite3 not available in python, skipping build directory lock")
|
||||
|
|
|
@ -603,7 +603,7 @@ fn test_item() {
|
|||
stringify_item!(
|
||||
impl<T> Struct<T> {}
|
||||
),
|
||||
"impl <T> Struct<T> {}", // FIXME
|
||||
"impl<T> Struct<T> {}",
|
||||
);
|
||||
assert_eq!(
|
||||
stringify_item!(
|
||||
|
@ -611,6 +611,12 @@ fn test_item() {
|
|||
),
|
||||
"pub impl Trait for Struct {}",
|
||||
);
|
||||
assert_eq!(
|
||||
stringify_item!(
|
||||
impl<T> const Trait for T {}
|
||||
),
|
||||
"impl<T> const Trait for T {}",
|
||||
);
|
||||
assert_eq!(
|
||||
stringify_item!(
|
||||
impl ~const Struct {}
|
||||
|
|
25
src/test/ui/mir/drop-elaboration-after-borrowck-error.rs
Normal file
25
src/test/ui/mir/drop-elaboration-after-borrowck-error.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Regression test for issue 81708 and issue 91816 where running a drop
|
||||
// elaboration on a MIR which failed borrowck lead to an ICE.
|
||||
|
||||
static A: () = {
|
||||
let a: [String; 1];
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
a[0] = String::new();
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
//~| ERROR use of possibly-uninitialized variable
|
||||
};
|
||||
|
||||
struct B<T>([T; 1]);
|
||||
|
||||
impl<T> B<T> {
|
||||
pub const fn f(mut self, other: T) -> Self {
|
||||
let _this = self;
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
self.0[0] = other;
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
//~| ERROR use of moved value
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
57
src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr
Normal file
57
src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr
Normal file
|
@ -0,0 +1,57 @@
|
|||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:7:5
|
||||
|
|
||||
LL | a[0] = String::new();
|
||||
| ^^^^
|
||||
| |
|
||||
| statics cannot evaluate destructors
|
||||
| value is dropped here
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:5:9
|
||||
|
|
||||
LL | let a: [String; 1];
|
||||
| ^ statics cannot evaluate destructors
|
||||
...
|
||||
LL | };
|
||||
| - value is dropped here
|
||||
|
||||
error[E0381]: use of possibly-uninitialized variable: `a`
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:7:5
|
||||
|
|
||||
LL | a[0] = String::new();
|
||||
| ^^^^ use of possibly-uninitialized `a`
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
|
||||
|
|
||||
LL | self.0[0] = other;
|
||||
| ^^^^^^^^^
|
||||
| |
|
||||
| constant functions cannot evaluate destructors
|
||||
| value is dropped here
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:16:13
|
||||
|
|
||||
LL | let _this = self;
|
||||
| ^^^^^ constant functions cannot evaluate destructors
|
||||
...
|
||||
LL | }
|
||||
| - value is dropped here
|
||||
|
||||
error[E0382]: use of moved value: `self.0`
|
||||
--> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
|
||||
|
|
||||
LL | pub const fn f(mut self, other: T) -> Self {
|
||||
| -------- move occurs because `self` has type `B<T>`, which does not implement the `Copy` trait
|
||||
LL | let _this = self;
|
||||
| ---- value moved here
|
||||
LL |
|
||||
LL | self.0[0] = other;
|
||||
| ^^^^^^^^^ value used here after move
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0381, E0382, E0493.
|
||||
For more information about an error, try `rustc --explain E0381`.
|
Loading…
Add table
Reference in a new issue