Auto merge of #70667 - flip1995:clippyup, r=Manishearth
Update Clippy
r? @Manishearth
Closes #70663
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 350f7be..6501ba0 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -79,7 +79,7 @@
};
match layout.fields {
- layout::FieldPlacement::Union(_) => {
+ layout::FieldsShape::Union(_) => {
let fill = cx.type_padding_filler(layout.size, layout.align.abi);
let packed = false;
match name {
@@ -91,10 +91,10 @@
}
}
}
- layout::FieldPlacement::Array { count, .. } => {
+ layout::FieldsShape::Array { count, .. } => {
cx.type_array(layout.field(cx, 0).llvm_type(cx), count)
}
- layout::FieldPlacement::Arbitrary { .. } => match name {
+ layout::FieldsShape::Arbitrary { .. } => match name {
None => {
let (llfields, packed) = struct_llfields(cx, layout);
cx.type_struct(&llfields, packed)
@@ -371,13 +371,13 @@
_ => {}
}
match self.fields {
- layout::FieldPlacement::Union(_) => {
+ layout::FieldsShape::Union(_) => {
bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self)
}
- layout::FieldPlacement::Array { .. } => index as u64,
+ layout::FieldsShape::Array { .. } => index as u64,
- layout::FieldPlacement::Arbitrary { .. } => {
+ layout::FieldsShape::Arbitrary { .. } => {
1 + (self.fields.memory_index(index) as u64) * 2
}
}
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 1237e70..eca66a5 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -66,7 +66,7 @@
}
pub fn len<Cx: ConstMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
- if let layout::FieldPlacement::Array { count, .. } = self.layout.fields {
+ if let layout::FieldsShape::Array { count, .. } = self.layout.fields {
if self.layout.is_unsized() {
assert_eq!(count, 0);
self.llextra.unwrap()
diff --git a/src/librustc_error_codes/error_codes/E0468.md b/src/librustc_error_codes/error_codes/E0468.md
index 73e3ebb..cf86647 100644
--- a/src/librustc_error_codes/error_codes/E0468.md
+++ b/src/librustc_error_codes/error_codes/E0468.md
@@ -1,4 +1,4 @@
-A non-root module attempts to import macros from another crate.
+A non-root module tried to import macros from another crate.
Example of erroneous code:
@@ -17,7 +17,7 @@
This will work:
```
-#[macro_use(debug_assert)]
+#[macro_use(debug_assert)] // ok!
extern crate core;
mod foo {
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index c46ab89..d46f1bc 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -53,9 +53,8 @@
#[derive(Debug)]
pub struct FrameInfo<'tcx> {
- /// This span is in the caller.
- pub call_site: Span,
pub instance: ty::Instance<'tcx>,
+ pub span: Span,
pub lint_root: Option<hir::HirId>,
}
@@ -65,12 +64,12 @@
if tcx.def_key(self.instance.def_id()).disambiguated_data.data
== DefPathData::ClosureExpr
{
- write!(f, "inside call to closure")?;
+ write!(f, "inside closure")?;
} else {
- write!(f, "inside call to `{}`", self.instance)?;
+ write!(f, "inside `{}`", self.instance)?;
}
- if !self.call_site.is_dummy() {
- let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo());
+ if !self.span.is_dummy() {
+ let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo());
write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?;
}
Ok(())
@@ -168,13 +167,10 @@
if let Some(span_msg) = span_msg {
err.span_label(self.span, span_msg);
}
- // Add spans for the stacktrace.
- // Skip the last, which is just the environment of the constant. The stacktrace
- // is sometimes empty because we create "fake" eval contexts in CTFE to do work
- // on constant values.
- if !self.stacktrace.is_empty() {
- for frame_info in &self.stacktrace[..self.stacktrace.len() - 1] {
- err.span_label(frame_info.call_site, frame_info.to_string());
+ // Add spans for the stacktrace. Don't print a single-line backtrace though.
+ if self.stacktrace.len() > 1 {
+ for frame_info in &self.stacktrace {
+ err.span_label(frame_info.span, frame_info.to_string());
}
}
// Let the caller finish the job.
diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs
index 1847326..a2793f9 100644
--- a/src/librustc_middle/traits/specialization_graph.rs
+++ b/src/librustc_middle/traits/specialization_graph.rs
@@ -154,14 +154,44 @@
}
}
-pub struct NodeItem<T> {
- pub node: Node,
- pub item: T,
+/// Information about the most specialized definition of an associated item.
+pub struct LeafDef {
+ /// The associated item described by this `LeafDef`.
+ pub item: ty::AssocItem,
+
+ /// The node in the specialization graph containing the definition of `item`.
+ pub defining_node: Node,
+
+ /// The "top-most" (ie. least specialized) specialization graph node that finalized the
+ /// definition of `item`.
+ ///
+ /// Example:
+ ///
+ /// ```
+ /// trait Tr {
+ /// fn assoc(&self);
+ /// }
+ ///
+ /// impl<T> Tr for T {
+ /// default fn assoc(&self) {}
+ /// }
+ ///
+ /// impl Tr for u8 {}
+ /// ```
+ ///
+ /// If we start the leaf definition search at `impl Tr for u8`, that impl will be the
+ /// `finalizing_node`, while `defining_node` will be the generic impl.
+ ///
+ /// If the leaf definition search is started at the generic impl, `finalizing_node` will be
+ /// `None`, since the most specialized impl we found still allows overriding the method
+ /// (doesn't finalize it).
+ pub finalizing_node: Option<Node>,
}
-impl<T> NodeItem<T> {
- pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> NodeItem<U> {
- NodeItem { node: self.node, item: f(self.item) }
+impl LeafDef {
+ /// Returns whether this definition is known to not be further specializable.
+ pub fn is_final(&self) -> bool {
+ self.finalizing_node.is_some()
}
}
@@ -173,18 +203,36 @@
tcx: TyCtxt<'tcx>,
trait_item_name: Ident,
trait_item_kind: ty::AssocKind,
- ) -> Option<NodeItem<ty::AssocItem>> {
+ ) -> Option<LeafDef> {
let trait_def_id = self.trait_def_id;
+ let mut finalizing_node = None;
+
self.find_map(|node| {
- node.item(tcx, trait_item_name, trait_item_kind, trait_def_id)
- .map(|item| NodeItem { node, item })
+ if let Some(item) = node.item(tcx, trait_item_name, trait_item_kind, trait_def_id) {
+ if finalizing_node.is_none() {
+ let is_specializable = item.defaultness.is_default()
+ || tcx.impl_defaultness(node.def_id()).is_default();
+
+ if !is_specializable {
+ finalizing_node = Some(node);
+ }
+ }
+
+ Some(LeafDef { item, defining_node: node, finalizing_node })
+ } else {
+ // Item not mentioned. This "finalizes" any defaulted item provided by an ancestor.
+ finalizing_node = Some(node);
+ None
+ }
})
}
}
/// Walk up the specialization ancestors of a given impl, starting with that
-/// impl itself. Returns `None` if an error was reported while building the
-/// specialization graph.
+/// impl itself.
+///
+/// Returns `Err` if an error was reported while building the specialization
+/// graph.
pub fn ancestors(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 17c9392..727d302 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -230,7 +230,7 @@
// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`.
// This is used to go between `memory_index` (source field order to memory order)
// and `inverse_memory_index` (memory order to source field order).
-// See also `FieldPlacement::Arbitrary::memory_index` for more details.
+// See also `FieldsShape::Arbitrary::memory_index` for more details.
// FIXME(eddyb) build a better abstraction for permutations, if possible.
fn invert_mapping(map: &[u32]) -> Vec<u32> {
let mut inverse = vec![0; map.len()];
@@ -257,7 +257,7 @@
Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Arbitrary {
+ fields: FieldsShape::Arbitrary {
offsets: vec![Size::ZERO, b_offset],
memory_index: vec![0, 1],
},
@@ -443,7 +443,7 @@
};
let pair = self.scalar_pair(a.clone(), b.clone());
let pair_offsets = match pair.fields {
- FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
+ FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
assert_eq!(memory_index, &[0, 1]);
offsets
}
@@ -471,7 +471,7 @@
Ok(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Arbitrary { offsets, memory_index },
+ fields: FieldsShape::Arbitrary { offsets, memory_index },
abi,
largest_niche,
align,
@@ -520,7 +520,7 @@
// The never type.
ty::Never => tcx.intern_layout(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Union(0),
+ fields: FieldsShape::Union(0),
abi: Abi::Uninhabited,
largest_niche: None,
align: dl.i8_align,
@@ -581,7 +581,7 @@
tcx.intern_layout(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Array { stride: element.size, count },
+ fields: FieldsShape::Array { stride: element.size, count },
abi,
largest_niche,
align: element.align,
@@ -592,7 +592,7 @@
let element = self.layout_of(element)?;
tcx.intern_layout(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Array { stride: element.size, count: 0 },
+ fields: FieldsShape::Array { stride: element.size, count: 0 },
abi: Abi::Aggregate { sized: false },
largest_niche: None,
align: element.align,
@@ -601,7 +601,7 @@
}
ty::Str => tcx.intern_layout(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Array { stride: Size::from_bytes(1), count: 0 },
+ fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 },
abi: Abi::Aggregate { sized: false },
largest_niche: None,
align: dl.i8_align,
@@ -670,7 +670,7 @@
tcx.intern_layout(Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Array { stride: element.size, count },
+ fields: FieldsShape::Array { stride: element.size, count },
abi: Abi::Vector { element: scalar, count },
largest_niche: element.largest_niche.clone(),
size,
@@ -746,7 +746,7 @@
return Ok(tcx.intern_layout(Layout {
variants: Variants::Single { index },
- fields: FieldPlacement::Union(variants[index].len()),
+ fields: FieldsShape::Union(variants[index].len()),
abi,
largest_niche: None,
align,
@@ -980,7 +980,7 @@
discr_index: 0,
variants: st,
},
- fields: FieldPlacement::Arbitrary {
+ fields: FieldsShape::Arbitrary {
offsets: vec![offset],
memory_index: vec![0],
},
@@ -1121,7 +1121,7 @@
let new_ity_size = ity.size();
for variant in &mut layout_variants {
match variant.fields {
- FieldPlacement::Arbitrary { ref mut offsets, .. } => {
+ FieldsShape::Arbitrary { ref mut offsets, .. } => {
for i in offsets {
if *i <= old_ity_size {
assert_eq!(*i, old_ity_size);
@@ -1151,7 +1151,7 @@
let mut common_prim = None;
for (field_layouts, layout_variant) in variants.iter().zip(&layout_variants) {
let offsets = match layout_variant.fields {
- FieldPlacement::Arbitrary { ref offsets, .. } => offsets,
+ FieldsShape::Arbitrary { ref offsets, .. } => offsets,
_ => bug!(),
};
let mut fields =
@@ -1187,7 +1187,7 @@
if let Some((prim, offset)) = common_prim {
let pair = self.scalar_pair(tag.clone(), scalar_unit(prim));
let pair_offsets = match pair.fields {
- FieldPlacement::Arbitrary { ref offsets, ref memory_index } => {
+ FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
assert_eq!(memory_index, &[0, 1]);
offsets
}
@@ -1218,7 +1218,7 @@
discr_index: 0,
variants: layout_variants,
},
- fields: FieldPlacement::Arbitrary {
+ fields: FieldsShape::Arbitrary {
offsets: vec![Size::ZERO],
memory_index: vec![0],
},
@@ -1435,7 +1435,7 @@
// GeneratorLayout.
debug!("prefix = {:#?}", prefix);
let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields {
- FieldPlacement::Arbitrary { mut offsets, memory_index } => {
+ FieldsShape::Arbitrary { mut offsets, memory_index } => {
let mut inverse_memory_index = invert_mapping(&memory_index);
// "a" (`0..b_start`) and "b" (`b_start..`) correspond to
@@ -1458,7 +1458,7 @@
let memory_index_b = invert_mapping(&inverse_memory_index_b);
let outer_fields =
- FieldPlacement::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
+ FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a };
(outer_fields, offsets_b, memory_index_b)
}
_ => bug!(),
@@ -1492,7 +1492,7 @@
variant.variants = Variants::Single { index };
let (offsets, memory_index) = match variant.fields {
- FieldPlacement::Arbitrary { offsets, memory_index } => (offsets, memory_index),
+ FieldsShape::Arbitrary { offsets, memory_index } => (offsets, memory_index),
_ => bug!(),
};
@@ -1535,7 +1535,7 @@
combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX);
let combined_memory_index = invert_mapping(&combined_inverse_memory_index);
- variant.fields = FieldPlacement::Arbitrary {
+ variant.fields = FieldsShape::Arbitrary {
offsets: combined_offsets,
memory_index: combined_memory_index,
};
@@ -1990,7 +1990,7 @@
if index == variant_index &&
// Don't confuse variants of uninhabited enums with the enum itself.
// For more details see https://github.com/rust-lang/rust/issues/69763.
- this.fields != FieldPlacement::Union(0) =>
+ this.fields != FieldsShape::Union(0) =>
{
this.layout
}
@@ -2008,7 +2008,7 @@
let tcx = cx.tcx();
tcx.intern_layout(Layout {
variants: Variants::Single { index: variant_index },
- fields: FieldPlacement::Union(fields),
+ fields: FieldsShape::Union(fields),
abi: Abi::Uninhabited,
largest_niche: None,
align: tcx.data_layout.i8_align,
@@ -2054,7 +2054,7 @@
// Reuse the fat `*T` type as its own thin pointer data field.
// This provides information about, e.g., DST struct pointees
// (which may have no non-DST form), and will work as long
- // as the `Abi` or `FieldPlacement` is checked by users.
+ // as the `Abi` or `FieldsShape` is checked by users.
if i == 0 {
let nil = tcx.mk_unit();
let ptr_ty = if this.ty.is_unsafe_ptr() {
@@ -2219,7 +2219,7 @@
if let Some(variant) = data_variant {
// We're not interested in any unions.
- if let FieldPlacement::Union(_) = variant.fields {
+ if let FieldsShape::Union(_) = variant.fields {
data_variant = None;
}
}
diff --git a/src/librustc_mir/const_eval/error.rs b/src/librustc_mir/const_eval/error.rs
index f722784..f7e28cf 100644
--- a/src/librustc_mir/const_eval/error.rs
+++ b/src/librustc_mir/const_eval/error.rs
@@ -55,6 +55,6 @@
mut error: InterpErrorInfo<'tcx>,
) -> ConstEvalErr<'tcx> {
error.print_backtrace();
- let stacktrace = ecx.generate_stacktrace(None);
+ let stacktrace = ecx.generate_stacktrace();
ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span }
}
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index c30d41e..af79198 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -46,7 +46,6 @@
ecx.push_stack_frame(
cid.instance,
- body.span,
body,
Some(ret.into()),
StackPopCleanup::None { cleanup: false },
diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs
index ee6fab4..e926347 100644
--- a/src/librustc_mir/const_eval/machine.rs
+++ b/src/librustc_mir/const_eval/machine.rs
@@ -8,9 +8,9 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_ast::ast::Mutability;
+use rustc_hir::def_id::DefId;
use rustc_middle::mir::AssertMessage;
use rustc_span::symbol::Symbol;
-use rustc_span::{def_id::DefId, Span};
use crate::interpret::{
self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
@@ -64,7 +64,6 @@
/// If this returns successfully (`Ok`), the function should just be evaluated normally.
fn hook_panic_fn(
&mut self,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
) -> InterpResult<'tcx> {
@@ -77,7 +76,7 @@
let msg_place = self.deref_operand(args[0])?;
let msg = Symbol::intern(self.read_str(msg_place)?);
- let span = self.find_closest_untracked_caller_location().unwrap_or(span);
+ let span = self.find_closest_untracked_caller_location();
let (file, line, col) = self.location_triple_for_span(span);
Err(ConstEvalErrKind::Panic { msg, file, line, col }.into())
} else {
@@ -191,7 +190,6 @@
fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
@@ -213,7 +211,7 @@
} else {
// Some functions we support even if they are non-const -- but avoid testing
// that for const fn!
- ecx.hook_panic_fn(span, instance, args)?;
+ ecx.hook_panic_fn(instance, args)?;
// We certainly do *not* want to actually call the fn
// though, so be sure we return here.
throw_unsup_format!("calling non-const function `{}`", instance)
@@ -248,13 +246,12 @@
fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
- if ecx.emulate_intrinsic(span, instance, args, ret)? {
+ if ecx.emulate_intrinsic(instance, args, ret)? {
return Ok(());
}
// An intrinsic that we do not support
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index d204be7..8f24fc4 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -17,7 +17,7 @@
use rustc_middle::ty::query::TyCtxtAt;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_span::source_map::{self, Span, DUMMY_SP};
+use rustc_span::source_map::DUMMY_SP;
use super::{
Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, OpTy, Operand, Place, PlaceTy,
@@ -57,9 +57,6 @@
/// The def_id and substs of the current function.
pub instance: ty::Instance<'tcx>,
- /// The span of the call site.
- pub span: source_map::Span,
-
/// Extra data for the machine.
pub extra: Extra,
@@ -502,7 +499,6 @@
pub fn push_stack_frame(
&mut self,
instance: ty::Instance<'tcx>,
- span: Span,
body: &'mir mir::Body<'tcx>,
return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
@@ -522,7 +518,6 @@
// empty local array, we fill it in below, after we are inside the stack frame and
// all methods actually know about the frame
locals: IndexVec::new(),
- span,
instance,
stmt: 0,
extra,
@@ -541,7 +536,6 @@
// statics and constants don't have `Storage*` statements, no need to look for them
Some(DefKind::Static) | Some(DefKind::Const) | Some(DefKind::AssocConst) => {}
_ => {
- trace!("push_stack_frame: {:?}: num_bbs: {}", span, body.basic_blocks().len());
for block in body.basic_blocks() {
for stmt in block.statements.iter() {
use rustc_middle::mir::StatementKind::{StorageDead, StorageLive};
@@ -859,33 +853,21 @@
}
}
- pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
- let mut last_span = None;
+ pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
let mut frames = Vec::new();
for frame in self.stack().iter().rev() {
- // make sure we don't emit frames that are duplicates of the previous
- if explicit_span == Some(frame.span) {
- last_span = Some(frame.span);
- continue;
- }
- if let Some(last) = last_span {
- if last == frame.span {
- continue;
- }
- } else {
- last_span = Some(frame.span);
- }
-
- let lint_root = frame.current_source_info().and_then(|source_info| {
+ let source_info = frame.current_source_info();
+ let lint_root = source_info.and_then(|source_info| {
match &frame.body.source_scopes[source_info.scope].local_data {
mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
mir::ClearCrossCrate::Clear => None,
}
});
+ let span = source_info.map_or(DUMMY_SP, |source_info| source_info.span);
- frames.push(FrameInfo { call_site: frame.span, instance: frame.instance, lint_root });
+ frames.push(FrameInfo { span, instance: frame.instance, lint_root });
}
- trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
+ trace!("generate stacktrace: {:#?}", frames);
frames
}
}
@@ -899,7 +881,6 @@
fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
self.body.hash_stable(hcx, hasher);
self.instance.hash_stable(hcx, hasher);
- self.span.hash_stable(hcx, hasher);
self.return_to_block.hash_stable(hcx, hasher);
self.return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
self.locals.hash_stable(hcx, hasher);
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index c5f7a94..b60377f 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -15,7 +15,6 @@
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::{sym, Symbol};
-use rustc_span::Span;
use super::{ImmTy, InterpCx, Machine, OpTy, PlaceTy};
@@ -78,7 +77,6 @@
/// Returns `true` if emulation happened.
pub fn emulate_intrinsic(
&mut self,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
@@ -101,7 +99,7 @@
// `src/librustc_middle/ty/constness.rs`
match intrinsic_name {
sym::caller_location => {
- let span = self.find_closest_untracked_caller_location().unwrap_or(span);
+ let span = self.find_closest_untracked_caller_location();
let location = self.alloc_caller_location_for_span(span);
self.write_scalar(location.ptr, dest)?;
}
@@ -118,7 +116,7 @@
sym::needs_drop => self.tcx.types.bool,
sym::type_id => self.tcx.types.u64,
sym::type_name => self.tcx.mk_static_str(),
- _ => span_bug!(span, "Already checked for nullary intrinsics"),
+ _ => bug!("already checked for nullary intrinsics"),
};
let val = self.const_eval(gid, ty)?;
self.copy_op(val, dest)?;
diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs
index 37b01d6..f7e264b 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs
@@ -12,18 +12,21 @@
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
- /// frame which is not `#[track_caller]`. If the first frame found lacks `#[track_caller]`, then
- /// `None` is returned and the callsite of the function invocation itself should be used.
- crate fn find_closest_untracked_caller_location(&self) -> Option<Span> {
- let mut caller_span = None;
- for next_caller in self.stack.iter().rev() {
- if !next_caller.instance.def.requires_caller_location(*self.tcx) {
- return caller_span;
- }
- caller_span = Some(next_caller.span);
- }
-
- caller_span
+ /// frame which is not `#[track_caller]`.
+ crate fn find_closest_untracked_caller_location(&self) -> Span {
+ self.stack
+ .iter()
+ .rev()
+ // Find first non-`#[track_caller]` frame.
+ .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx))
+ // Assert that there is always such a frame.
+ .unwrap()
+ .current_source_info()
+ // Assert that the frame we look at is actually executing code currently
+ // (`current_source_info` is None when we are unwinding and the frame does
+ // not require cleanup).
+ .unwrap()
+ .span
}
/// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index faee041..48082a1 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -7,7 +7,7 @@
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty};
-use rustc_span::{def_id::DefId, Span};
+use rustc_span::def_id::DefId;
use super::{
AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
@@ -135,7 +135,6 @@
/// was used.
fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
@@ -156,7 +155,6 @@
/// responsibility to advance the instruction pointer as appropriate.
fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
- span: Span,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 5c4915d..a8e65a7 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -219,7 +219,7 @@
// Go through the layout. There are lots of types that support a length,
// e.g., SIMD types.
match self.layout.fields {
- layout::FieldPlacement::Array { count, .. } => Ok(count),
+ layout::FieldsShape::Array { count, .. } => Ok(count),
_ => bug!("len not supported on sized type {:?}", self.layout.ty),
}
}
@@ -437,7 +437,7 @@
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
// Not using the layout method because we want to compute on u64
match base.layout.fields {
- layout::FieldPlacement::Array { stride, .. } => {
+ layout::FieldsShape::Array { stride, .. } => {
let len = base.len(self)?;
if index >= len {
// This can only be reached in ConstProp and non-rustc-MIR.
@@ -463,7 +463,7 @@
{
let len = base.len(self)?; // also asserts that we have a type where this makes sense
let stride = match base.layout.fields {
- layout::FieldPlacement::Array { stride, .. } => stride,
+ layout::FieldsShape::Array { stride, .. } => stride,
_ => bug!("mplace_array_fields: expected an array layout"),
};
let layout = base.layout.field(self, 0)?;
@@ -493,7 +493,7 @@
// Not using layout method because that works with usize, and does not work with slices
// (that have count 0 in their layout).
let from_offset = match base.layout.fields {
- layout::FieldPlacement::Array { stride, .. } => stride * from, // `Size` multiplication is checked
+ layout::FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked
_ => bug!("Unexpected layout of index access: {:#?}", base.layout),
};
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 0c2aa28..6ca6f50 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -4,7 +4,6 @@
use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
use rustc_middle::ty::Instance;
use rustc_middle::{mir, ty};
-use rustc_span::source_map::Span;
use rustc_target::spec::abi::Abi;
use super::{
@@ -71,14 +70,7 @@
Some((dest, ret)) => Some((self.eval_place(dest)?, ret)),
None => None,
};
- self.eval_fn_call(
- fn_val,
- terminator.source_info.span,
- abi,
- &args[..],
- ret,
- *cleanup,
- )?;
+ self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
}
Drop { location, target, unwind } => {
@@ -88,7 +80,7 @@
trace!("TerminatorKind::drop: {:?}, type {}", location, ty);
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
- self.drop_in_place(place, instance, terminator.source_info.span, target, unwind)?;
+ self.drop_in_place(place, instance, target, unwind)?;
}
Assert { ref cond, expected, ref msg, target, cleanup } => {
@@ -196,7 +188,6 @@
fn eval_fn_call(
&mut self,
fn_val: FnVal<'tcx, M::ExtraFnVal>,
- span: Span,
caller_abi: Abi,
args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
@@ -242,7 +233,7 @@
match instance.def {
ty::InstanceDef::Intrinsic(..) => {
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
- M::call_intrinsic(self, span, instance, args, ret, unwind)
+ M::call_intrinsic(self, instance, args, ret, unwind)
}
ty::InstanceDef::VtableShim(..)
| ty::InstanceDef::ReifyShim(..)
@@ -252,14 +243,13 @@
| ty::InstanceDef::CloneShim(..)
| ty::InstanceDef::Item(_) => {
// We need MIR for this fn
- let body = match M::find_mir_or_eval_fn(self, span, instance, args, ret, unwind)? {
+ let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? {
Some(body) => body,
None => return Ok(()),
};
self.push_stack_frame(
instance,
- span,
body,
ret.map(|p| p.0),
StackPopCleanup::Goto { ret: ret.map(|p| p.1), unwind },
@@ -407,7 +397,7 @@
OpTy::from(ImmTy { layout: this_receiver_ptr, imm: receiver_place.ptr.into() });
trace!("Patched self operand to {:#?}", args[0]);
// recurse with concrete function
- self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind)
+ self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind)
}
}
}
@@ -416,7 +406,6 @@
&mut self,
place: PlaceTy<'tcx, M::PointerTag>,
instance: ty::Instance<'tcx>,
- span: Span,
target: mir::BasicBlock,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
@@ -444,7 +433,6 @@
self.eval_fn_call(
FnVal::Instance(instance),
- span,
Abi::Rust,
&[arg.into()],
Some((dest.into(), target)),
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index 1117016..66a46c1 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -207,10 +207,10 @@
// Visit the fields of this value.
match v.layout().fields {
- layout::FieldPlacement::Union(fields) => {
+ layout::FieldsShape::Union(fields) => {
self.visit_union(v, fields)?;
},
- layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
+ layout::FieldsShape::Arbitrary { ref offsets, .. } => {
// FIXME: We collect in a vec because otherwise there are lifetime
// errors: Projecting to a field needs access to `ecx`.
let fields: Vec<InterpResult<'tcx, Self::V>> =
@@ -220,7 +220,7 @@
.collect();
self.visit_aggregate(v, fields.into_iter())?;
},
- layout::FieldPlacement::Array { .. } => {
+ layout::FieldsShape::Array { .. } => {
// Let's get an mplace first.
let mplace = v.to_op(self.ecx())?.assert_mem_place(self.ecx());
// Now we can go over all the fields.
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index b51c614..f4cba87 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -183,7 +183,6 @@
fn find_mir_or_eval_fn(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
- _span: Span,
_instance: ty::Instance<'tcx>,
_args: &[OpTy<'tcx>],
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
@@ -204,7 +203,6 @@
fn call_intrinsic(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
- _span: Span,
_instance: ty::Instance<'tcx>,
_args: &[OpTy<'tcx>],
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
@@ -361,7 +359,6 @@
ecx.push_stack_frame(
Instance::new(def_id, substs),
- span,
dummy_body,
ret.map(Into::into),
StackPopCleanup::None { cleanup: false },
diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs
index 285cb5f..81de630 100644
--- a/src/librustc_target/abi/call/mips64.rs
+++ b/src/librustc_target/abi/call/mips64.rs
@@ -49,7 +49,7 @@
// use of float registers to structures (not unions) containing exactly one or two
// float fields.
- if let abi::FieldPlacement::Arbitrary { .. } = ret.layout.fields {
+ if let abi::FieldsShape::Arbitrary { .. } = ret.layout.fields {
if ret.layout.fields.count() == 1 {
if let Some(reg) = float_reg(cx, ret, 0) {
ret.cast_to(reg);
@@ -88,15 +88,15 @@
let mut prefix_index = 0;
match arg.layout.fields {
- abi::FieldPlacement::Array { .. } => {
+ abi::FieldsShape::Array { .. } => {
// Arrays are passed indirectly
arg.make_indirect();
return;
}
- abi::FieldPlacement::Union(_) => {
+ abi::FieldsShape::Union(_) => {
// Unions and are always treated as a series of 64-bit integer chunks
}
- abi::FieldPlacement::Arbitrary { .. } => {
+ abi::FieldsShape::Arbitrary { .. } => {
// Structures are split up into a series of 64-bit integer chunks, but any aligned
// doubles not part of another aggregate are passed as floats.
let mut last_offset = Size::ZERO;
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 72768c3..b6bfa70 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -1,4 +1,4 @@
-use crate::abi::{self, Abi, Align, FieldPlacement, Size};
+use crate::abi::{self, Abi, Align, FieldsShape, Size};
use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
use crate::spec::{self, HasTargetSpec};
@@ -315,7 +315,7 @@
start: Size|
-> Result<(HomogeneousAggregate, Size), Heterogeneous> {
let is_union = match layout.fields {
- FieldPlacement::Array { count, .. } => {
+ FieldsShape::Array { count, .. } => {
assert_eq!(start, Size::ZERO);
let result = if count > 0 {
@@ -325,8 +325,8 @@
};
return Ok((result, layout.size));
}
- FieldPlacement::Union(_) => true,
- FieldPlacement::Arbitrary { .. } => false,
+ FieldsShape::Union(_) => true,
+ FieldsShape::Arbitrary { .. } => false,
};
let mut result = HomogeneousAggregate::NoData;
diff --git a/src/librustc_target/abi/call/riscv.rs b/src/librustc_target/abi/call/riscv.rs
index a916a53..0eb8816 100644
--- a/src/librustc_target/abi/call/riscv.rs
+++ b/src/librustc_target/abi/call/riscv.rs
@@ -6,7 +6,7 @@
use crate::abi::call::{ArgAbi, ArgAttribute, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
use crate::abi::{
- self, Abi, FieldPlacement, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods,
+ self, Abi, FieldsShape, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods,
};
use crate::spec::HasTargetSpec;
@@ -87,12 +87,12 @@
},
Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv),
Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields {
- FieldPlacement::Union(_) => {
+ FieldsShape::Union(_) => {
if !arg_layout.is_zst() {
return Err(CannotUseFpConv);
}
}
- FieldPlacement::Array { count, .. } => {
+ FieldsShape::Array { count, .. } => {
for _ in 0..count {
let elem_layout = arg_layout.field(cx, 0);
should_use_fp_conv_helper(
@@ -105,7 +105,7 @@
)?;
}
}
- FieldPlacement::Arbitrary { .. } => {
+ FieldsShape::Arbitrary { .. } => {
match arg_layout.variants {
abi::Variants::Multiple { .. } => return Err(CannotUseFpConv),
abi::Variants::Single { .. } => (),
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 3cc7292..f382ef9 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -618,7 +618,7 @@
/// Describes how the fields of a type are located in memory.
#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)]
-pub enum FieldPlacement {
+pub enum FieldsShape {
/// All fields start at no offset. The `usize` is the field count.
///
/// In the case of primitives the number of fields is `0`.
@@ -657,38 +657,38 @@
},
}
-impl FieldPlacement {
+impl FieldsShape {
pub fn count(&self) -> usize {
match *self {
- FieldPlacement::Union(count) => count,
- FieldPlacement::Array { count, .. } => {
+ FieldsShape::Union(count) => count,
+ FieldsShape::Array { count, .. } => {
let usize_count = count as usize;
assert_eq!(usize_count as u64, count);
usize_count
}
- FieldPlacement::Arbitrary { ref offsets, .. } => offsets.len(),
+ FieldsShape::Arbitrary { ref offsets, .. } => offsets.len(),
}
}
pub fn offset(&self, i: usize) -> Size {
match *self {
- FieldPlacement::Union(count) => {
+ FieldsShape::Union(count) => {
assert!(i < count, "tried to access field {} of union with {} fields", i, count);
Size::ZERO
}
- FieldPlacement::Array { stride, count } => {
+ FieldsShape::Array { stride, count } => {
let i = u64::try_from(i).unwrap();
assert!(i < count);
stride * i
}
- FieldPlacement::Arbitrary { ref offsets, .. } => offsets[i],
+ FieldsShape::Arbitrary { ref offsets, .. } => offsets[i],
}
}
pub fn memory_index(&self, i: usize) -> usize {
match *self {
- FieldPlacement::Union(_) | FieldPlacement::Array { .. } => i,
- FieldPlacement::Arbitrary { ref memory_index, .. } => {
+ FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
+ FieldsShape::Arbitrary { ref memory_index, .. } => {
let r = memory_index[i];
assert_eq!(r as usize as u32, r);
r as usize
@@ -704,7 +704,7 @@
let use_small = self.count() <= inverse_small.len();
// We have to write this logic twice in order to keep the array small.
- if let FieldPlacement::Arbitrary { ref memory_index, .. } = *self {
+ if let FieldsShape::Arbitrary { ref memory_index, .. } = *self {
if use_small {
for i in 0..self.count() {
inverse_small[memory_index[i] as usize] = i as u8;
@@ -718,8 +718,8 @@
}
(0..self.count()).map(move |i| match *self {
- FieldPlacement::Union(_) | FieldPlacement::Array { .. } => i,
- FieldPlacement::Arbitrary { .. } => {
+ FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
+ FieldsShape::Arbitrary { .. } => {
if use_small {
inverse_small[i] as usize
} else {
@@ -888,7 +888,7 @@
pub struct Layout {
/// Says where the fields are located within the layout.
/// Primitives and uninhabited enums appear as unions without fields.
- pub fields: FieldPlacement,
+ pub fields: FieldsShape,
/// Encodes information about multi-variant layouts.
/// Even with `Multiple` variants, a layout still has its own fields! Those are then
@@ -923,7 +923,7 @@
let align = scalar.value.align(cx);
Layout {
variants: Variants::Single { index: VariantIdx::new(0) },
- fields: FieldPlacement::Union(0),
+ fields: FieldsShape::Union(0),
abi: Abi::Scalar(scalar),
largest_niche,
size,
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 3ef44a1..5f98850 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -54,7 +54,6 @@
};
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
-pub use self::specialize::find_associated_item;
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
@@ -64,8 +63,7 @@
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
pub use self::util::{
- get_vtable_index_of_object_method, impl_is_default, impl_item_is_final,
- predicate_for_trait_def, upcast_choices,
+ get_vtable_index_of_object_method, impl_item_is_final, predicate_for_trait_def, upcast_choices,
};
pub use self::util::{
supertrait_def_ids, supertraits, transitive_bounds, SupertraitDefIds, Supertraits,
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index 2eb63b8..aae0d46 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -1015,49 +1015,21 @@
assoc_ty_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
.map_err(|ErrorReported| ())?;
- let is_default = if node_item.node.is_from_trait() {
- // If true, the impl inherited a `type Foo = Bar`
- // given in the trait, which is implicitly default.
- // Otherwise, the impl did not specify `type` and
- // neither did the trait:
- //
- // ```rust
- // trait Foo { type T; }
- // impl Foo for Bar { }
- // ```
- //
- // This is an error, but it will be
- // reported in `check_impl_items_against_trait`.
- // We accept it here but will flag it as
- // an error when we confirm the candidate
- // (which will ultimately lead to `normalize_to_error`
- // being invoked).
- false
+ if node_item.is_final() {
+ // Non-specializable items are always projectable.
+ true
} else {
- // If we're looking at a trait *impl*, the item is
- // specializable if the impl or the item are marked
- // `default`.
- node_item.item.defaultness.is_default()
- || super::util::impl_is_default(selcx.tcx(), node_item.node.def_id())
- };
-
- match is_default {
- // Non-specializable items are always projectable
- false => true,
-
// Only reveal a specializable default if we're past type-checking
// and the obligation is monomorphic, otherwise passes such as
// transmute checking and polymorphic MIR optimizations could
// get a result which isn't correct for all monomorphizations.
- true if obligation.param_env.reveal == Reveal::All => {
+ if obligation.param_env.reveal == Reveal::All {
// NOTE(eddyb) inference variables can resolve to parameters, so
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
let poly_trait_ref =
selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
!poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
- }
-
- true => {
+ } else {
debug!(
"assemble_candidates_from_impls: not eligible due to default: \
assoc_ty={} predicate={}",
@@ -1422,7 +1394,8 @@
return Progress { ty: tcx.types.err, obligations: nested };
}
let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
- let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
+ let substs =
+ translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.defining_node);
let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind {
let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id);
tcx.mk_opaque(assoc_ty.item.def_id, item_substs)
@@ -1447,7 +1420,7 @@
selcx: &SelectionContext<'_, '_>,
impl_def_id: DefId,
assoc_ty_def_id: DefId,
-) -> Result<specialization_graph::NodeItem<ty::AssocItem>, ErrorReported> {
+) -> Result<specialization_graph::LeafDef, ErrorReported> {
let tcx = selcx.tcx();
let assoc_ty_name = tcx.associated_item(assoc_ty_def_id).ident;
let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
@@ -1464,9 +1437,10 @@
if matches!(item.kind, ty::AssocKind::Type | ty::AssocKind::OpaqueTy)
&& tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id)
{
- return Ok(specialization_graph::NodeItem {
- node: specialization_graph::Node::Impl(impl_def_id),
+ return Ok(specialization_graph::LeafDef {
item: *item,
+ defining_node: impl_node,
+ finalizing_node: if item.defaultness.is_default() { None } else { Some(impl_node) },
});
}
}
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs
index edf02d7..fabd8c8 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/src/librustc_trait_selection/traits/specialize/mod.rs
@@ -20,7 +20,7 @@
use rustc_hir::def_id::DefId;
use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
use rustc_span::DUMMY_SP;
@@ -112,48 +112,6 @@
source_substs.rebase_onto(infcx.tcx, source_impl, target_substs)
}
-/// Given a selected impl described by `impl_data`, returns the
-/// definition and substitutions for the method with the name `name`
-/// the kind `kind`, and trait method substitutions `substs`, in
-/// that impl, a less specialized impl, or the trait default,
-/// whichever applies.
-pub fn find_associated_item<'tcx>(
- tcx: TyCtxt<'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- item: &ty::AssocItem,
- substs: SubstsRef<'tcx>,
- impl_data: &super::VtableImplData<'tcx, ()>,
-) -> (DefId, SubstsRef<'tcx>) {
- debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", param_env, item, substs, impl_data);
- assert!(!substs.needs_infer());
-
- let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
- let trait_def = tcx.trait_def(trait_def_id);
-
- if let Ok(ancestors) = trait_def.ancestors(tcx, impl_data.impl_def_id) {
- match ancestors.leaf_def(tcx, item.ident, item.kind) {
- Some(node_item) => {
- let substs = tcx.infer_ctxt().enter(|infcx| {
- let param_env = param_env.with_reveal_all();
- let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
- let substs = translate_substs(
- &infcx,
- param_env,
- impl_data.impl_def_id,
- substs,
- node_item.node,
- );
- infcx.tcx.erase_regions(&substs)
- });
- (node_item.item.def_id, substs)
- }
- None => bug!("{:?} not found in {:?}", item, impl_data.impl_def_id),
- }
- } else {
- (item.def_id, substs)
- }
-}
-
/// Is `impl1` a specialization of `impl2`?
///
/// Specialization is determined by the sets of types to which the impls apply;
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index 6eeac2f..6348673 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -4,7 +4,6 @@
use smallvec::SmallVec;
use rustc_data_structures::fx::FxHashSet;
-use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
@@ -651,22 +650,8 @@
ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
}
-pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool {
- match tcx.hir().as_local_hir_id(node_item_def_id) {
- Some(hir_id) => {
- let item = tcx.hir().expect_item(hir_id);
- if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
- defaultness.is_default()
- } else {
- false
- }
- }
- None => tcx.impl_defaultness(node_item_def_id).is_default(),
- }
-}
-
pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
- assoc_item.defaultness.is_final() && !impl_is_default(tcx, assoc_item.container.id())
+ assoc_item.defaultness.is_final() && tcx.impl_defaultness(assoc_item.container.id()).is_final()
}
pub enum TupleArgumentsFlag {
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 447c49e..47c4b1c 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -1,9 +1,11 @@
use rustc_hir::def_id::DefId;
+use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Instance, TyCtxt, TypeFoldable};
use rustc_span::sym;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
+use traits::{translate_substs, Reveal};
use log::debug;
@@ -82,21 +84,50 @@
// the actual function:
match vtbl {
traits::VtableImpl(impl_data) => {
- let (def_id, substs) =
- traits::find_associated_item(tcx, param_env, trait_item, rcvr_substs, &impl_data);
+ debug!(
+ "resolving VtableImpl: {:?}, {:?}, {:?}, {:?}",
+ param_env, trait_item, rcvr_substs, impl_data
+ );
+ assert!(!rcvr_substs.needs_infer());
+ assert!(!trait_ref.needs_infer());
- let resolved_item = tcx.associated_item(def_id);
+ let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap();
+ let trait_def = tcx.trait_def(trait_def_id);
+ let leaf_def = trait_def
+ .ancestors(tcx, impl_data.impl_def_id)
+ .ok()?
+ .leaf_def(tcx, trait_item.ident, trait_item.kind)
+ .unwrap_or_else(|| {
+ bug!("{:?} not found in {:?}", trait_item, impl_data.impl_def_id);
+ });
+ let def_id = leaf_def.item.def_id;
+
+ let substs = tcx.infer_ctxt().enter(|infcx| {
+ let param_env = param_env.with_reveal_all();
+ let substs = rcvr_substs.rebase_onto(tcx, trait_def_id, impl_data.substs);
+ let substs = translate_substs(
+ &infcx,
+ param_env,
+ impl_data.impl_def_id,
+ substs,
+ leaf_def.defining_node,
+ );
+ infcx.tcx.erase_regions(&substs)
+ });
// Since this is a trait item, we need to see if the item is either a trait default item
// or a specialization because we can't resolve those unless we can `Reveal::All`.
// NOTE: This should be kept in sync with the similar code in
// `rustc_middle::traits::project::assemble_candidates_from_impls()`.
- let eligible = if !resolved_item.defaultness.is_default() {
+ let eligible = if leaf_def.is_final() {
+ // Non-specializable items are always projectable.
true
- } else if param_env.reveal == traits::Reveal::All {
- !trait_ref.needs_subst()
} else {
- false
+ // Only reveal a specializable default if we're past type-checking
+ // and the obligation is monomorphic, otherwise passes such as
+ // transmute checking and polymorphic MIR optimizations could
+ // get a result which isn't correct for all monomorphizations.
+ if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false }
};
if !eligible {
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index 9d28447..aefe61f 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -165,6 +165,16 @@
)
}
+fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
+ let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
+ let item = tcx.hir().expect_item(hir_id);
+ if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
+ defaultness
+ } else {
+ bug!("`impl_defaultness` called on {:?}", item);
+ }
+}
+
/// Calculates the `Sized` constraint.
///
/// In fact, there are only a few options for the types in the constraint:
@@ -371,6 +381,7 @@
crate_hash,
instance_def_size_estimate,
issue33140_self_ty,
+ impl_defaultness,
..*providers
};
}
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6249e1d..3823efe 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1942,7 +1942,7 @@
// grandparent. In that case, if parent is a `default impl`, inherited items use the
// "defaultness" from the grandparent, else they are final.
None => {
- if traits::impl_is_default(tcx, parent_impl.def_id()) {
+ if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
None
} else {
Some(Err(parent_impl.def_id()))
@@ -2114,10 +2114,10 @@
for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
let is_implemented = ancestors
.leaf_def(tcx, trait_item.ident, trait_item.kind)
- .map(|node_item| !node_item.node.is_from_trait())
+ .map(|node_item| !node_item.defining_node.is_from_trait())
.unwrap_or(false);
- if !is_implemented && !traits::impl_is_default(tcx, impl_id) {
+ if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
if !trait_item.defaultness.has_value() {
missing_items.push(*trait_item);
}
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
index cede356..f1e9192 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr
@@ -5,7 +5,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| transmuting to uninhabited type
- | inside call to `foo` at $DIR/validate_uninhabited_zsts.rs:14:26
+ | inside `foo` at $DIR/validate_uninhabited_zsts.rs:5:14
+ | inside `FOO` at $DIR/validate_uninhabited_zsts.rs:14:26
...
LL | const FOO: [Empty; 3] = [foo(); 3];
| -----------------------------------
diff --git a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
index c7e9021..8ed1431 100644
--- a/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
+++ b/src/test/ui/consts/miri_unleashed/abi-mismatch.stderr
@@ -17,7 +17,8 @@
| ^^^^^^^
| |
| calling a function with ABI C using caller ABI Rust
- | inside call to `call_rust_fn` at $DIR/abi-mismatch.rs:13:17
+ | inside `call_rust_fn` at $DIR/abi-mismatch.rs:9:5
+ | inside `VAL` at $DIR/abi-mismatch.rs:13:17
...
LL | const VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| --------------------------------------------------------------------------------------
diff --git a/src/test/ui/consts/miri_unleashed/drop.stderr b/src/test/ui/consts/miri_unleashed/drop.stderr
index 2439d52..5d560fa 100644
--- a/src/test/ui/consts/miri_unleashed/drop.stderr
+++ b/src/test/ui/consts/miri_unleashed/drop.stderr
@@ -12,12 +12,15 @@
LL | | // real drop glue by the compiler.
LL | | drop_in_place(to_drop)
LL | | }
- | |_^ calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
+ | | ^
+ | | |
+ | |_calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
+ | inside `std::intrinsics::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at $SRC_DIR/libcore/ptr/mod.rs:LL:COL
|
::: $DIR/drop.rs:23:1
|
LL | };
- | - inside call to `std::intrinsics::drop_in_place::<std::vec::Vec<i32>> - shim(Some(std::vec::Vec<i32>))` at $DIR/drop.rs:23:1
+ | - inside `TEST_BAD` at $DIR/drop.rs:23:1
error: aborting due to previous error
diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr
index 2175307..f1a183b 100644
--- a/src/test/ui/consts/offset_from_ub.stderr
+++ b/src/test/ui/consts/offset_from_ub.stderr
@@ -5,7 +5,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| ptr_offset_from cannot compute offset of pointers into different allocations.
- | inside call to `std::ptr::const_ptr::<impl *const Struct>::offset_from` at $DIR/offset_from_ub.rs:22:27
+ | inside `std::ptr::const_ptr::<impl *const Struct>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
+ | inside `DIFFERENT_ALLOC` at $DIR/offset_from_ub.rs:22:27
|
::: $DIR/offset_from_ub.rs:16:1
|
@@ -27,7 +28,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| unable to turn bytes into a pointer
- | inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:28:14
+ | inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
+ | inside `NOT_PTR` at $DIR/offset_from_ub.rs:28:14
|
::: $DIR/offset_from_ub.rs:26:1
|
@@ -44,7 +46,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| exact_div: 1isize cannot be divided by 2isize without remainder
- | inside call to `std::ptr::const_ptr::<impl *const u16>::offset_from` at $DIR/offset_from_ub.rs:36:14
+ | inside `std::ptr::const_ptr::<impl *const u16>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
+ | inside `NOT_MULTIPLE_OF_SIZE` at $DIR/offset_from_ub.rs:36:14
|
::: $DIR/offset_from_ub.rs:31:1
|
@@ -64,7 +67,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| invalid use of NULL pointer
- | inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:42:14
+ | inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
+ | inside `OFFSET_FROM_NULL` at $DIR/offset_from_ub.rs:42:14
|
::: $DIR/offset_from_ub.rs:39:1
|
@@ -82,7 +86,8 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| unable to turn bytes into a pointer
- | inside call to `std::ptr::const_ptr::<impl *const u8>::offset_from` at $DIR/offset_from_ub.rs:49:14
+ | inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
+ | inside `DIFFERENT_INT` at $DIR/offset_from_ub.rs:49:14
|
::: $DIR/offset_from_ub.rs:45:1
|
diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
index 1f3e2cf..ca23238 100644
--- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr
+++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr
@@ -4,76 +4,140 @@
LL | hint_unreachable()
| ------------------
| |
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
- | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
...
LL | fake_type()
| ^^^^^^^^^^^
| |
| reached the configured maximum number of stack frames
- | inside call to `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
+ | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
error: any use of this value will cause an error
--> $DIR/uninhabited-const-issue-61744.rs:12:36
diff --git a/src/test/ui/specialization/issue-70442.rs b/src/test/ui/specialization/issue-70442.rs
new file mode 100644
index 0000000..4371dd2
--- /dev/null
+++ b/src/test/ui/specialization/issue-70442.rs
@@ -0,0 +1,23 @@
+#![feature(specialization)]
+
+// check-pass
+
+trait Trait {
+ type Assoc;
+}
+
+impl<T> Trait for T {
+ default type Assoc = bool;
+}
+
+// This impl inherits the `Assoc` definition from above and "locks it in", or finalizes it, making
+// child impls unable to further specialize it. However, since the specialization graph didn't
+// correctly track this, we would refuse to project `Assoc` from this impl, even though that should
+// happen for items that are final.
+impl Trait for () {}
+
+fn foo<X: Trait<Assoc=bool>>() {}
+
+fn main() {
+ foo::<()>(); // `<() as Trait>::Assoc` is normalized to `bool` correctly
+}
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index cf00cb1..6968822 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -58,13 +58,6 @@
// This takes much less time to build than all of Servo and supports stable Rust.
packages: &["selectors"],
},
- Test {
- name: "webrender",
- repo: "https://github.com/servo/webrender",
- sha: "a3d6e6894c5a601fa547c6273eb963ca1321c2bb",
- lock: None,
- packages: &[],
- },
];
fn main() {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 0ee016f..8a291a3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -180,29 +180,25 @@
}
fn print_diff(expected: &str, actual: &str, context_size: usize) {
- write_diff(expected, actual, context_size, std::io::stdout());
-}
-
-fn write_diff(expected: &str, actual: &str, context_size: usize, mut dest: impl io::Write) {
let diff_results = make_diff(expected, actual, context_size);
for result in diff_results {
let mut line_number = result.line_number;
for line in result.lines {
match line {
DiffLine::Expected(e) => {
- writeln!(dest, "-\t{}", e).unwrap();
+ println!("-\t{}", e);
line_number += 1;
}
DiffLine::Context(c) => {
- writeln!(dest, "{}\t{}", line_number, c).unwrap();
+ println!("{}\t{}", line_number, c);
line_number += 1;
}
DiffLine::Resulting(r) => {
- writeln!(dest, "+\t{}", r).unwrap();
+ println!("+\t{}", r);
}
}
}
- writeln!(dest).unwrap();
+ println!();
}
}