Skip to content

Commit

Permalink
Return ErrorGuaranteed from items_of_instance query
Browse files Browse the repository at this point in the history
Signed-off-by: FedericoBruzzone <federico.bruzzone.i@gmail.com>
  • Loading branch information
FedericoBruzzone committed Jan 15, 2025
1 parent e347b48 commit e860813
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 23 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ impl EraseType for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
type Result = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
}

impl<T> EraseType for Result<(&'_ [T], &'_ [T]), rustc_errors::ErrorGuaranteed> {
type Result =
[u8; size_of::<Result<(&'static [()], &'static [()]), rustc_errors::ErrorGuaranteed>>()];
}

impl<T> EraseType for Option<&'_ T> {
type Result = [u8; size_of::<Option<&'static ()>>()];
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2492,7 +2492,12 @@ rustc_queries! {
desc { "functions to skip for move-size check" }
}

query items_of_instance(key: (ty::Instance<'tcx>, CollectionMode)) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
query items_of_instance(
key: (ty::Instance<'tcx>, CollectionMode)
) -> Result<
(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]),
ErrorGuaranteed
> {
desc { "collecting items used by `{}`", key.0 }
cache_on_disk_if { true }
}
Expand Down
32 changes: 21 additions & 11 deletions compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ use rustc_middle::{bug, span_bug};
use rustc_session::Limit;
use rustc_session::config::EntryFnType;
use rustc_span::source_map::{Spanned, dummy_spanned, respan};
use rustc_span::{DUMMY_SP, Span};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use tracing::{debug, instrument, trace};

use crate::errors::{self, EncounteredErrorWhileInstantiating, NoOptimizedMir, RecursionLimit};
Expand Down Expand Up @@ -466,9 +466,11 @@ fn collect_items_rec<'tcx>(
));

rustc_data_structures::stack::ensure_sufficient_stack(|| {
let (used, mentioned) = tcx.items_of_instance((instance, mode));
used_items.extend(used.into_iter().copied());
mentioned_items.extend(mentioned.into_iter().copied());
// FIXME: we could handle the `ErrorGuaranteed` generated by `tcx.eval_instance`.
if let Ok((used, mentioned)) = tcx.items_of_instance((instance, mode)) {
used_items.extend(used.into_iter().copied());
mentioned_items.extend(mentioned.into_iter().copied());
};
});
}
MonoItem::GlobalAsm(item_id) => {
Expand Down Expand Up @@ -626,6 +628,8 @@ struct MirUsedCollector<'a, 'tcx> {
/// Note that this contains *not-monomorphized* items!
used_mentioned_items: &'a mut UnordSet<MentionedItem<'tcx>>,
instance: Instance<'tcx>,
/// If an error is encountered during const evaluation.
tained_by_errors: Option<ErrorGuaranteed>,
}

impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
Expand Down Expand Up @@ -658,9 +662,10 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
"collection encountered polymorphic constant: {:?}",
const_
),
Err(err @ ErrorHandled::Reported(..)) => {
Err(err @ ErrorHandled::Reported(reported, _)) => {
err.emit_note(self.tcx);
return None;
self.tained_by_errors = Some(reported.into());
None
}
}
}
Expand Down Expand Up @@ -1211,7 +1216,7 @@ fn collect_items_of_instance<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
mode: CollectionMode,
) -> (MonoItems<'tcx>, MonoItems<'tcx>) {
) -> Result<(MonoItems<'tcx>, MonoItems<'tcx>), ErrorGuaranteed> {
// This item is getting monomorphized, do mono-time checks.
tcx.ensure().check_mono_item(instance);

Expand All @@ -1235,6 +1240,7 @@ fn collect_items_of_instance<'tcx>(
used_items: &mut used_items,
used_mentioned_items: &mut used_mentioned_items,
instance,
tained_by_errors: None,
};

if mode == CollectionMode::UsedItems {
Expand All @@ -1260,19 +1266,23 @@ fn collect_items_of_instance<'tcx>(
}
}

(used_items, mentioned_items)
if let Some(err) = collector.tained_by_errors {
return Err(err);
}

Ok((used_items, mentioned_items))
}

fn items_of_instance<'tcx>(
tcx: TyCtxt<'tcx>,
(instance, mode): (Instance<'tcx>, CollectionMode),
) -> (&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]) {
let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode);
) -> Result<(&'tcx [Spanned<MonoItem<'tcx>>], &'tcx [Spanned<MonoItem<'tcx>>]), ErrorGuaranteed> {
let (used_items, mentioned_items) = collect_items_of_instance(tcx, instance, mode)?;

let used_items = tcx.arena.alloc_from_iter(used_items);
let mentioned_items = tcx.arena.alloc_from_iter(mentioned_items);

(used_items, mentioned_items)
Ok((used_items, mentioned_items))
}

/// `item` must be already monomorphized.
Expand Down
22 changes: 12 additions & 10 deletions src/librustdoc/html/templates/type_layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ <h2 id="layout" class="section-header"> {# #}
{% endfor %}
</ul>
{% endif %}
{# This kind of layout error can occur with valid code, e.g. if you try to
get the layout of a generic type such as `Vec<T>`. #}
{# This kind of layout error can occur with valid code.
It can happen for various reasons, e.g., if you try to get
the layout of an array with a length that is not a constant
and it has not a generic parameter such as
`[(); size_of::<<() as Trait>::Assoc>()]`. #}
{% when Err(LayoutError::Unknown(_)) %}
<p> {# #}
<strong>Note:</strong> Unable to compute type layout, {#+ #}
possibly due to this type having generic parameters. {#+ #}
Layout can only be computed for concrete, fully-instantiated types. {# #}
<strong>Note:</strong> Unable to compute type layout. {#+ #}
It can happen for various reasons. {# #}
</p>
{# This kind of error probably can't happen with valid code, but we don't
want to panic and prevent the docs from building, so we just let the
Expand All @@ -44,13 +46,13 @@ <h2 id="layout" class="section-header"> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type was too big. {# #}
</p>
{# This kind of error probably can't happen with valid code, but we don't
want to panic and prevent the docs from building, so we just let the
user know that we couldn't compute the layout. #}
{# This kind of layout error can occur with valid code, e.g. if you try to
get the layout of a generic type such as `Vec<T>`. #}
{% when Err(LayoutError::TooGeneric(_)) %}
<p> {# #}
<strong>Note:</strong> Encountered an error during type layout; {#+ #}
the type was too generic. {# #}
<strong>Note:</strong> Unable to compute type layout, {#+ #}
possibly due to this type having generic parameters. {#+ #}
Layout can only be computed for concrete, fully-instantiated types. {# #}
</p>
{% when Err(LayoutError::ReferencesError(_)) %}
<p> {# #}
Expand Down
6 changes: 6 additions & 0 deletions tests/rustdoc/type-layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,9 @@ pub enum Uninhabited {}
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
//@ hasraw - '8 bytes (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>)'
pub struct Uninhabited2(std::convert::Infallible, u64);

pub trait Project { type Assoc; }
// We can't compute layout. A `LayoutError::Unknown` is returned.
//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout. It can happen for various reasons.'
//@ !hasraw - 'Size: '
pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project;
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl<T, const L: u8> VirtualWrapper<T, L> {
impl<T: MyTrait + 'static, const L: u8> MyTrait for VirtualWrapper<T, L> {
fn virtualize(&self) -> &dyn MyTrait {
unsafe { virtualize_my_trait(L, self) }
// unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem
// unsafe { virtualize_my_trait(L, &self.0) } // <-- this code fixes the problem
}
}

Expand Down
18 changes: 18 additions & 0 deletions tests/ui/polymorphic-const-2-issue-105249.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ check-pass

fn pass_to_ptr_call<T>(f: fn(T), x: T) {
f(x);
}

trait TrackedTrait {
fn trait_tracked_unit_default(_: ()) {
let location = std::panic::Location::caller();
assert_eq!(location.file(), file!());
}
}

impl TrackedTrait for () {}

fn main() {
pass_to_ptr_call(<() as TrackedTrait>::trait_tracked_unit_default, ());
}
15 changes: 15 additions & 0 deletions tests/ui/polymorphic-const-issue-105249.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//@ check-pass

trait Foo<T> {
fn print<'a>(&'a self) where T: 'a { println!("foo"); }
}

impl<'a> Foo<&'a ()> for () { }

trait Bar: for<'a> Foo<&'a ()> { }

impl Bar for () {}

fn main() {
(&() as &dyn Bar).print();
}
16 changes: 16 additions & 0 deletions tests/ui/print-mono-items-issue-105249.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ check-pass

// When -Zprint-mono-items=eager option was used, the following
// code previously caused an ICE.

pub struct S();

pub trait X {
fn unused3(var: i32) {
println!("{}", var);
}
}

impl X for S {}

fn main() {}

0 comments on commit e860813

Please sign in to comment.