mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #91221 - matthiaskrgr:rollup-iuz3gxq, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #89359 (Various fixes for const_trait_impl) - #90499 (Link with default MACOSX_DEPLOYMENT_TARGET if not otherwise specified.) - #91096 (Print associated types on opaque `impl Trait` types) - #91111 (Do not visit attributes in `ItemLowerer`.) - #91162 (explain why CTFE/Miri perform truncation on shift offset) - #91185 (Remove `-Z force-overflow-checks`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
37a49713cb
@ -40,6 +40,11 @@ impl ItemLowerer<'_, '_, '_> {
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
|
||||
fn visit_attribute(&mut self, _: &'a Attribute) {
|
||||
// We do not want to lower expressions that appear in attributes,
|
||||
// as they are not accessible to the rest of the HIR.
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'a Item) {
|
||||
let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| {
|
||||
let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item));
|
||||
|
@ -130,7 +130,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
let signed = left_layout.abi.is_signed();
|
||||
let size = u128::from(left_layout.size.bits());
|
||||
let overflow = r >= size;
|
||||
let r = r % size; // mask to type size
|
||||
// The shift offset is implicitly masked to the type size, to make sure this operation
|
||||
// is always defined. This is the one MIR operator that does *not* directly map to a
|
||||
// single LLVM operation. See
|
||||
// <https://github.com/rust-lang/rust/blob/a3b9405ae7bb6ab4e8103b414e75c44598a10fd2/compiler/rustc_codegen_ssa/src/common.rs#L131-L158>
|
||||
// for the corresponding truncation in our codegen backends.
|
||||
let r = r % size;
|
||||
let r = u32::try_from(r).unwrap(); // we masked so this will always fit
|
||||
let result = if signed {
|
||||
let l = self.sign_extend(l, left_layout) as i128;
|
||||
|
@ -1004,11 +1004,12 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
let mut err_span = self.span;
|
||||
let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
|
||||
|
||||
let ty_needs_non_const_drop = qualifs::NeedsNonConstDrop::in_any_value_of_ty(
|
||||
self.ccx,
|
||||
dropped_place.ty(self.body, self.tcx).ty,
|
||||
);
|
||||
let ty_needs_non_const_drop =
|
||||
qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
|
||||
|
||||
debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop);
|
||||
|
||||
if !ty_needs_non_const_drop {
|
||||
return;
|
||||
|
@ -268,6 +268,7 @@ language_item_table! {
|
||||
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None;
|
||||
Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1);
|
||||
GeneratorReturn, sym::generator_return, generator_return, Target::AssocTy, GenericRequirement::None;
|
||||
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
|
||||
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;
|
||||
|
||||
|
@ -726,7 +726,6 @@ fn test_debugging_options_tracking_hash() {
|
||||
tracked!(dep_info_omit_d_target, true);
|
||||
tracked!(dual_proc_macros, true);
|
||||
tracked!(fewer_names, Some(true));
|
||||
tracked!(force_overflow_checks, Some(true));
|
||||
tracked!(force_unstable_if_unmarked, true);
|
||||
tracked!(fuel, Some(("abc".to_string(), 99)));
|
||||
tracked!(function_sections, Some(false));
|
||||
|
@ -2246,8 +2246,12 @@ pub enum BinOp {
|
||||
/// The `*` operator (multiplication)
|
||||
Mul,
|
||||
/// The `/` operator (division)
|
||||
///
|
||||
/// Division by zero is UB.
|
||||
Div,
|
||||
/// The `%` operator (modulus)
|
||||
///
|
||||
/// Using zero as the modulus (second operand) is UB.
|
||||
Rem,
|
||||
/// The `^` operator (bitwise xor)
|
||||
BitXor,
|
||||
@ -2256,8 +2260,12 @@ pub enum BinOp {
|
||||
/// The `|` operator (bitwise or)
|
||||
BitOr,
|
||||
/// The `<<` operator (shift left)
|
||||
///
|
||||
/// The offset is truncated to the size of the first operand before shifting.
|
||||
Shl,
|
||||
/// The `>>` operator (shift right)
|
||||
///
|
||||
/// The offset is truncated to the size of the first operand before shifting.
|
||||
Shr,
|
||||
/// The `==` operator (equality)
|
||||
Eq,
|
||||
|
@ -7,6 +7,7 @@ pub mod query;
|
||||
pub mod select;
|
||||
pub mod specialization_graph;
|
||||
mod structural_impls;
|
||||
pub mod util;
|
||||
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::thir::abstract_const::NotConstEvaluatable;
|
||||
|
49
compiler/rustc_middle/src/traits/util.rs
Normal file
49
compiler/rustc_middle/src/traits/util.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use rustc_data_structures::stable_set::FxHashSet;
|
||||
|
||||
use crate::ty::{PolyTraitRef, TyCtxt};
|
||||
|
||||
/// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits.
|
||||
///
|
||||
/// A simplfied version of the same function at `rustc_infer::traits::util::supertraits`.
|
||||
pub fn supertraits<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: PolyTraitRef<'tcx>,
|
||||
) -> impl Iterator<Item = PolyTraitRef<'tcx>> {
|
||||
Elaborator { tcx, visited: FxHashSet::from_iter([trait_ref]), stack: vec![trait_ref] }
|
||||
}
|
||||
|
||||
struct Elaborator<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
visited: FxHashSet<PolyTraitRef<'tcx>>,
|
||||
stack: Vec<PolyTraitRef<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Elaborator<'tcx> {
|
||||
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
|
||||
let supertrait_refs = self
|
||||
.tcx
|
||||
.super_predicates_of(trait_ref.def_id())
|
||||
.predicates
|
||||
.into_iter()
|
||||
.flat_map(|(pred, _)| {
|
||||
pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_ref()
|
||||
})
|
||||
.map(|t| t.value)
|
||||
.filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
|
||||
|
||||
self.stack.extend(supertrait_refs);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Iterator for Elaborator<'tcx> {
|
||||
type Item = PolyTraitRef<'tcx>;
|
||||
|
||||
fn next(&mut self) -> Option<PolyTraitRef<'tcx>> {
|
||||
if let Some(trait_ref) = self.stack.pop() {
|
||||
self.elaborate(trait_ref);
|
||||
Some(trait_ref)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -643,81 +643,8 @@ pub trait PrettyPrinter<'tcx>:
|
||||
}
|
||||
return Ok(self);
|
||||
}
|
||||
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
|
||||
// by looking up the projections associated with the def_id.
|
||||
let bounds = self.tcx().explicit_item_bounds(def_id);
|
||||
|
||||
let mut first = true;
|
||||
let mut is_sized = false;
|
||||
let mut is_future = false;
|
||||
let mut future_output_ty = None;
|
||||
|
||||
p!("impl");
|
||||
for (predicate, _) in bounds {
|
||||
let predicate = predicate.subst(self.tcx(), substs);
|
||||
let bound_predicate = predicate.kind();
|
||||
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateKind::Projection(projection_predicate) => {
|
||||
let Some(future_trait) = self.tcx().lang_items().future_trait() else { continue };
|
||||
let future_output_def_id =
|
||||
self.tcx().associated_item_def_ids(future_trait)[0];
|
||||
|
||||
if projection_predicate.projection_ty.item_def_id
|
||||
== future_output_def_id
|
||||
{
|
||||
// We don't account for multiple `Future::Output = Ty` contraints.
|
||||
is_future = true;
|
||||
future_output_ty = Some(projection_predicate.ty);
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
let trait_ref = bound_predicate.rebind(pred.trait_ref);
|
||||
// Don't print +Sized, but rather +?Sized if absent.
|
||||
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait()
|
||||
{
|
||||
is_sized = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if Some(trait_ref.def_id())
|
||||
== self.tcx().lang_items().future_trait()
|
||||
{
|
||||
is_future = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
p!(
|
||||
write("{}", if first { " " } else { " + " }),
|
||||
print(trait_ref.print_only_trait_path())
|
||||
);
|
||||
|
||||
first = false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if is_future {
|
||||
p!(write("{}Future", if first { " " } else { " + " }));
|
||||
first = false;
|
||||
|
||||
if let Some(future_output_ty) = future_output_ty {
|
||||
// Don't print projection types, which we (unfortunately) see often
|
||||
// in the error outputs involving async blocks.
|
||||
if !matches!(future_output_ty.kind(), ty::Projection(_)) {
|
||||
p!("<Output = ", print(future_output_ty), ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !is_sized {
|
||||
p!(write("{}?Sized", if first { " " } else { " + " }));
|
||||
} else if first {
|
||||
p!(" Sized");
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
self.pretty_print_opaque_impl_type(def_id, substs)
|
||||
});
|
||||
}
|
||||
ty::Str => p!("str"),
|
||||
@ -826,6 +753,225 @@ pub trait PrettyPrinter<'tcx>:
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn pretty_print_opaque_impl_type(
|
||||
mut self,
|
||||
def_id: DefId,
|
||||
substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
|
||||
) -> Result<Self::Type, Self::Error> {
|
||||
define_scoped_cx!(self);
|
||||
|
||||
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
|
||||
// by looking up the projections associated with the def_id.
|
||||
let bounds = self.tcx().explicit_item_bounds(def_id);
|
||||
|
||||
let mut traits = BTreeMap::new();
|
||||
let mut fn_traits = BTreeMap::new();
|
||||
let mut is_sized = false;
|
||||
|
||||
for (predicate, _) in bounds {
|
||||
let predicate = predicate.subst(self.tcx(), substs);
|
||||
let bound_predicate = predicate.kind();
|
||||
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
let trait_ref = bound_predicate.rebind(pred.trait_ref);
|
||||
|
||||
// Don't print + Sized, but rather + ?Sized if absent.
|
||||
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
|
||||
is_sized = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits);
|
||||
}
|
||||
ty::PredicateKind::Projection(pred) => {
|
||||
let proj_ref = bound_predicate.rebind(pred);
|
||||
let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());
|
||||
|
||||
// Projection type entry -- the def-id for naming, and the ty.
|
||||
let proj_ty = (proj_ref.projection_def_id(), proj_ref.ty());
|
||||
|
||||
self.insert_trait_and_projection(
|
||||
trait_ref,
|
||||
Some(proj_ty),
|
||||
&mut traits,
|
||||
&mut fn_traits,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
|
||||
let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;
|
||||
|
||||
p!("impl");
|
||||
|
||||
for (fn_once_trait_ref, entry) in fn_traits {
|
||||
// Get the (single) generic ty (the args) of this FnOnce trait ref.
|
||||
let generics = self.generic_args_to_print(
|
||||
self.tcx().generics_of(fn_once_trait_ref.def_id()),
|
||||
fn_once_trait_ref.skip_binder().substs,
|
||||
);
|
||||
|
||||
match (entry.return_ty, generics[0].expect_ty()) {
|
||||
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
|
||||
// a return type.
|
||||
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
|
||||
let name = if entry.fn_trait_ref.is_some() {
|
||||
"Fn"
|
||||
} else if entry.fn_mut_trait_ref.is_some() {
|
||||
"FnMut"
|
||||
} else {
|
||||
"FnOnce"
|
||||
};
|
||||
|
||||
p!(
|
||||
write("{}", if first { " " } else { " + " }),
|
||||
write("{}{}(", if paren_needed { "(" } else { "" }, name)
|
||||
);
|
||||
|
||||
for (idx, ty) in arg_tys.tuple_fields().enumerate() {
|
||||
if idx > 0 {
|
||||
p!(", ");
|
||||
}
|
||||
p!(print(ty));
|
||||
}
|
||||
|
||||
p!(")");
|
||||
if !return_ty.skip_binder().is_unit() {
|
||||
p!("-> ", print(return_ty));
|
||||
}
|
||||
p!(write("{}", if paren_needed { ")" } else { "" }));
|
||||
|
||||
first = false;
|
||||
}
|
||||
// If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
|
||||
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
|
||||
_ => {
|
||||
if entry.has_fn_once {
|
||||
traits.entry(fn_once_trait_ref).or_default().extend(
|
||||
// Group the return ty with its def id, if we had one.
|
||||
entry
|
||||
.return_ty
|
||||
.map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)),
|
||||
);
|
||||
}
|
||||
if let Some(trait_ref) = entry.fn_mut_trait_ref {
|
||||
traits.entry(trait_ref).or_default();
|
||||
}
|
||||
if let Some(trait_ref) = entry.fn_trait_ref {
|
||||
traits.entry(trait_ref).or_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print the rest of the trait types (that aren't Fn* family of traits)
|
||||
for (trait_ref, assoc_items) in traits {
|
||||
p!(
|
||||
write("{}", if first { " " } else { " + " }),
|
||||
print(trait_ref.skip_binder().print_only_trait_name())
|
||||
);
|
||||
|
||||
let generics = self.generic_args_to_print(
|
||||
self.tcx().generics_of(trait_ref.def_id()),
|
||||
trait_ref.skip_binder().substs,
|
||||
);
|
||||
|
||||
if !generics.is_empty() || !assoc_items.is_empty() {
|
||||
p!("<");
|
||||
let mut first = true;
|
||||
|
||||
for ty in generics {
|
||||
if !first {
|
||||
p!(", ");
|
||||
}
|
||||
p!(print(trait_ref.rebind(*ty)));
|
||||
first = false;
|
||||
}
|
||||
|
||||
for (assoc_item_def_id, ty) in assoc_items {
|
||||
if !first {
|
||||
p!(", ");
|
||||
}
|
||||
p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident));
|
||||
|
||||
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
|
||||
match ty.skip_binder().kind() {
|
||||
ty::Projection(ty::ProjectionTy { item_def_id, .. })
|
||||
if Some(*item_def_id) == self.tcx().lang_items().generator_return() =>
|
||||
{
|
||||
p!("[async output]")
|
||||
}
|
||||
_ => {
|
||||
p!(print(ty))
|
||||
}
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
p!(">");
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
if !is_sized {
|
||||
p!(write("{}?Sized", if first { " " } else { " + " }));
|
||||
} else if first {
|
||||
p!(" Sized");
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Insert the trait ref and optionally a projection type associated with it into either the
|
||||
/// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
|
||||
fn insert_trait_and_projection(
|
||||
&mut self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
proj_ty: Option<(DefId, ty::Binder<'tcx, Ty<'tcx>>)>,
|
||||
traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, BTreeMap<DefId, ty::Binder<'tcx, Ty<'tcx>>>>,
|
||||
fn_traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
|
||||
) {
|
||||
let trait_def_id = trait_ref.def_id();
|
||||
|
||||
// If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
|
||||
// super-trait ref and record it there.
|
||||
if let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() {
|
||||
// If we have a FnOnce, then insert it into
|
||||
if trait_def_id == fn_once_trait {
|
||||
let entry = fn_traits.entry(trait_ref).or_default();
|
||||
// Optionally insert the return_ty as well.
|
||||
if let Some((_, ty)) = proj_ty {
|
||||
entry.return_ty = Some(ty);
|
||||
}
|
||||
entry.has_fn_once = true;
|
||||
return;
|
||||
} else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() {
|
||||
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
|
||||
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
|
||||
.unwrap();
|
||||
|
||||
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
|
||||
return;
|
||||
} else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() {
|
||||
let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
|
||||
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
|
||||
.unwrap();
|
||||
|
||||
fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just group our traits and projection types.
|
||||
traits.entry(trait_ref).or_default().extend(proj_ty);
|
||||
}
|
||||
|
||||
fn pretty_print_bound_var(
|
||||
&mut self,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
@ -2553,3 +2699,12 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers { trimmed_def_paths, ..*providers };
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OpaqueFnEntry<'tcx> {
|
||||
// The trait ref is already stored as a key, so just track if we have it as a real predicate
|
||||
has_fn_once: bool,
|
||||
fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
|
||||
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
|
||||
return_ty: Option<ty::Binder<'tcx, Ty<'tcx>>>,
|
||||
}
|
||||
|
@ -890,7 +890,7 @@ impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
|
||||
///
|
||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the substitutions.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub struct TraitRef<'tcx> {
|
||||
pub def_id: DefId,
|
||||
|
@ -173,6 +173,12 @@ impl<'tcx> CheckConstVisitor<'tcx> {
|
||||
None => return true,
|
||||
};
|
||||
|
||||
// If the function belongs to a trait, then it must enable the const_trait_impl
|
||||
// feature to use that trait function (with a const default body).
|
||||
if tcx.trait_of_item(def_id).is_some() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this crate is not using stability attributes, or this function is not claiming to be a
|
||||
// stable `const fn`, that is all that is required.
|
||||
if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
|
||||
|
@ -431,6 +431,10 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
|
||||
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
|
||||
impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||
fn visit_attribute(&mut self, _: &'ast Attribute) {
|
||||
// We do not want to resolve expressions that appear in attributes,
|
||||
// as they do not correspond to actual code.
|
||||
}
|
||||
fn visit_item(&mut self, item: &'ast Item) {
|
||||
let prev = replace(&mut self.diagnostic_metadata.current_item, Some(item));
|
||||
// Always report errors in items we just entered.
|
||||
|
@ -1131,8 +1131,6 @@ options! {
|
||||
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
|
||||
(default: no)"),
|
||||
force_overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"force overflow checks on or off"),
|
||||
force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
|
||||
"force all crates to be `rustc_private` unstable (default: no)"),
|
||||
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
|
||||
|
@ -678,11 +678,7 @@ impl Session {
|
||||
self.opts.debugging_opts.sanitizer.contains(SanitizerSet::CFI)
|
||||
}
|
||||
pub fn overflow_checks(&self) -> bool {
|
||||
self.opts
|
||||
.cg
|
||||
.overflow_checks
|
||||
.or(self.opts.debugging_opts.force_overflow_checks)
|
||||
.unwrap_or(self.opts.debug_assertions)
|
||||
self.opts.cg.overflow_checks.unwrap_or(self.opts.debug_assertions)
|
||||
}
|
||||
|
||||
/// Check whether this compile session and crate type use static crt.
|
||||
|
@ -679,6 +679,7 @@ symbols! {
|
||||
gen_future,
|
||||
gen_kill,
|
||||
generator,
|
||||
generator_return,
|
||||
generator_state,
|
||||
generators,
|
||||
generic_arg_infer,
|
||||
|
@ -9,19 +9,19 @@ pub fn target() -> Target {
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
|
||||
|
||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
|
||||
base.link_env.extend(super::apple_base::macos_link_env("arm64"));
|
||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||
|
||||
// Clang automatically chooses a more specific target based on
|
||||
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
|
||||
// correctly, we do too.
|
||||
let arch = "aarch64";
|
||||
let llvm_target = super::apple_base::macos_llvm_target(&arch);
|
||||
let llvm_target = super::apple_base::macos_llvm_target("arm64");
|
||||
|
||||
Target {
|
||||
llvm_target,
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(),
|
||||
arch: arch.to_string(),
|
||||
arch: "aarch64".to_string(),
|
||||
options: TargetOptions {
|
||||
mcount: "\u{1}mcount".to_string(),
|
||||
frame_pointer: FramePointer::NonLeaf,
|
||||
|
@ -13,8 +13,10 @@ pub fn opts(os: &str) -> TargetOptions {
|
||||
// warnings about the usage of ELF TLS.
|
||||
//
|
||||
// Here we detect what version is being requested, defaulting to 10.7. ELF
|
||||
// TLS is flagged as enabled if it looks to be supported.
|
||||
let version = macos_deployment_target();
|
||||
// TLS is flagged as enabled if it looks to be supported. The architecture
|
||||
// only matters for default deployment target which is 11.0 for ARM64 and
|
||||
// 10.7 for everything else.
|
||||
let has_elf_tls = macos_deployment_target("x86_64") >= (10, 7);
|
||||
|
||||
TargetOptions {
|
||||
os: os.to_string(),
|
||||
@ -31,7 +33,7 @@ pub fn opts(os: &str) -> TargetOptions {
|
||||
has_rpath: true,
|
||||
dll_suffix: ".dylib".to_string(),
|
||||
archive_format: "darwin".to_string(),
|
||||
has_elf_tls: version >= (10, 7),
|
||||
has_elf_tls,
|
||||
abi_return_struct_as_int: true,
|
||||
emit_debug_gdb_scripts: false,
|
||||
eh_frame_header: false,
|
||||
@ -63,15 +65,32 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> {
|
||||
.and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok())
|
||||
}
|
||||
|
||||
fn macos_deployment_target() -> (u32, u32) {
|
||||
deployment_target("MACOSX_DEPLOYMENT_TARGET").unwrap_or((10, 7))
|
||||
fn macos_default_deployment_target(arch: &str) -> (u32, u32) {
|
||||
if arch == "arm64" { (11, 0) } else { (10, 7) }
|
||||
}
|
||||
|
||||
fn macos_deployment_target(arch: &str) -> (u32, u32) {
|
||||
deployment_target("MACOSX_DEPLOYMENT_TARGET")
|
||||
.unwrap_or_else(|| macos_default_deployment_target(arch))
|
||||
}
|
||||
|
||||
pub fn macos_llvm_target(arch: &str) -> String {
|
||||
let (major, minor) = macos_deployment_target();
|
||||
let (major, minor) = macos_deployment_target(arch);
|
||||
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
|
||||
}
|
||||
|
||||
pub fn macos_link_env(arch: &str) -> Vec<(String, String)> {
|
||||
// Use the default deployment target for linking just as with the LLVM target if not
|
||||
// specified via MACOSX_DEPLOYMENT_TARGET, otherwise the system linker would use its
|
||||
// default which varies with Xcode version.
|
||||
if env::var("MACOSX_DEPLOYMENT_TARGET").is_err() {
|
||||
let default = macos_default_deployment_target(arch);
|
||||
vec![("MACOSX_DEPLOYMENT_TARGET".to_string(), format!("{}.{}", default.0, default.1))]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn macos_link_env_remove() -> Vec<String> {
|
||||
let mut env_remove = Vec::with_capacity(2);
|
||||
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
|
||||
|
@ -5,6 +5,7 @@ pub fn target() -> Target {
|
||||
base.cpu = "yonah".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
|
||||
base.link_env.extend(super::apple_base::macos_link_env("i686"));
|
||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
@ -10,6 +10,7 @@ pub fn target() -> Target {
|
||||
LinkerFlavor::Gcc,
|
||||
vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
|
||||
);
|
||||
base.link_env.extend(super::apple_base::macos_link_env("x86_64"));
|
||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
|
@ -304,7 +304,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&& obligation.predicate.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
||||
{
|
||||
if self.is_in_const_context {
|
||||
self.assemble_const_drop_candidates(obligation, &mut candidates)?;
|
||||
self.assemble_const_drop_candidates(obligation, stack, &mut candidates)?;
|
||||
} else {
|
||||
debug!("passing ~const Drop bound; in non-const context");
|
||||
// `~const Drop` when we are not in a const context has no effect.
|
||||
@ -911,9 +911,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn assemble_const_drop_candidates(
|
||||
fn assemble_const_drop_candidates<'a>(
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
obligation_stack: &TraitObligationStack<'a, 'tcx>,
|
||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||
) -> Result<(), SelectionError<'tcx>> {
|
||||
let mut stack: Vec<(Ty<'tcx>, usize)> = vec![(obligation.self_ty().skip_binder(), 0)];
|
||||
@ -922,7 +923,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let mut noreturn = false;
|
||||
|
||||
self.check_recursion_depth(depth, obligation)?;
|
||||
let mut copy_candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
|
||||
let mut new_candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
|
||||
let mut copy_obligation =
|
||||
obligation.with(obligation.predicate.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
@ -933,13 +934,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}));
|
||||
copy_obligation.recursion_depth = depth + 1;
|
||||
self.assemble_candidates_from_impls(©_obligation, &mut copy_candidates);
|
||||
self.assemble_candidates_from_impls(©_obligation, &mut new_candidates);
|
||||
let copy_conditions = self.copy_clone_conditions(©_obligation);
|
||||
self.assemble_builtin_bound_candidates(copy_conditions, &mut copy_candidates);
|
||||
if !copy_candidates.vec.is_empty() {
|
||||
self.assemble_builtin_bound_candidates(copy_conditions, &mut new_candidates);
|
||||
let copy_stack = self.push_stack(obligation_stack.list(), ©_obligation);
|
||||
self.assemble_candidates_from_caller_bounds(©_stack, &mut new_candidates)?;
|
||||
|
||||
let const_drop_obligation =
|
||||
obligation.with(obligation.predicate.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(hir::LangItem::Drop, None),
|
||||
substs: self.tcx().mk_substs_trait(ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}));
|
||||
|
||||
let const_drop_stack = self.push_stack(obligation_stack.list(), &const_drop_obligation);
|
||||
self.assemble_candidates_from_caller_bounds(&const_drop_stack, &mut new_candidates)?;
|
||||
|
||||
if !new_candidates.vec.is_empty() {
|
||||
noreturn = true;
|
||||
}
|
||||
debug!(?copy_candidates.vec, "assemble_const_drop_candidates - copy");
|
||||
debug!(?new_candidates.vec, "assemble_const_drop_candidates");
|
||||
|
||||
match ty.kind() {
|
||||
ty::Int(_)
|
||||
|
@ -82,6 +82,7 @@ pub trait Generator<R = ()> {
|
||||
/// `return` statement or implicitly as the last expression of a generator
|
||||
/// literal. For example futures would use this as `Result<T, E>` as it
|
||||
/// represents a completed future.
|
||||
#[cfg_attr(not(bootstrap), lang = "generator_return")]
|
||||
type Return;
|
||||
|
||||
/// Resumes the execution of this generator.
|
||||
|
@ -19,16 +19,16 @@
|
||||
+ _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-78442.rs:11:5: 11:13
|
||||
// + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) }
|
||||
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
- _2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
- _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
- // mir::Constant
|
||||
- // + span: $DIR/issue-78442.rs:11:5: 11:15
|
||||
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
|
||||
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
|
||||
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9
|
||||
let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3
|
||||
let _2: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
- let mut _3: &impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
- let _4: impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
+ let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
+ let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
@ -18,17 +18,17 @@
|
||||
_4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-78442.rs:11:5: 11:13
|
||||
// + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar(<ZST>)) }
|
||||
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
_3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15
|
||||
StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
_2 = <impl Fn<()> as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
_2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
|
||||
// mir::Constant
|
||||
// + span: $DIR/issue-78442.rs:11:5: 11:15
|
||||
// + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> <impl std::ops::Fn<()> as std::ops::FnOnce<()>>::Output {<impl std::ops::Fn<()> as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
|
||||
// + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb2: {
|
||||
|
@ -83,17 +83,17 @@ fn main() {
|
||||
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
|
||||
|
||||
accepts_trait(returns_opaque_foo());
|
||||
//~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
|
||||
//~^ ERROR type mismatch resolving `<impl Foo + Trait as Trait>::Associated == ()`
|
||||
|
||||
accepts_trait(returns_opaque_derived_foo());
|
||||
//~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
|
||||
//~^ ERROR type mismatch resolving `<impl Foo + DerivedTrait as Trait>::Associated == ()`
|
||||
|
||||
accepts_generic_trait(returns_opaque_generic());
|
||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||
|
||||
accepts_generic_trait(returns_opaque_generic_foo());
|
||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
|
||||
//~^ ERROR type mismatch resolving `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||
|
||||
accepts_generic_trait(returns_opaque_generic_duplicate());
|
||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
||||
//~^ ERROR type mismatch resolving `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ help: consider constraining the associated type `<impl DerivedTrait as Trait>::A
|
||||
LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Foo + Trait as Trait>::Associated == ()`
|
||||
--> $DIR/issue-87261.rs:85:5
|
||||
|
|
||||
LL | fn returns_opaque_foo() -> impl Trait + Foo {
|
||||
@ -170,18 +170,18 @@ LL | accepts_trait(returns_opaque_foo());
|
||||
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl Trait + Foo as Trait>::Associated`
|
||||
found associated type `<impl Foo + Trait as Trait>::Associated`
|
||||
note: required by a bound in `accepts_trait`
|
||||
--> $DIR/issue-87261.rs:43:27
|
||||
|
|
||||
LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
|
||||
help: consider constraining the associated type `<impl Trait + Foo as Trait>::Associated` to `()`
|
||||
help: consider constraining the associated type `<impl Foo + Trait as Trait>::Associated` to `()`
|
||||
|
|
||||
LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Foo + DerivedTrait as Trait>::Associated == ()`
|
||||
--> $DIR/issue-87261.rs:88:5
|
||||
|
|
||||
LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
|
||||
@ -191,8 +191,8 @@ LL | accepts_trait(returns_opaque_derived_foo());
|
||||
| ^^^^^^^^^^^^^ expected `()`, found associated type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
|
||||
= help: consider constraining the associated type `<impl DerivedTrait + Foo as Trait>::Associated` to `()`
|
||||
found associated type `<impl Foo + DerivedTrait as Trait>::Associated`
|
||||
= help: consider constraining the associated type `<impl Foo + DerivedTrait as Trait>::Associated` to `()`
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||
note: required by a bound in `accepts_trait`
|
||||
--> $DIR/issue-87261.rs:43:27
|
||||
@ -221,7 +221,7 @@ help: consider constraining the associated type `<impl GenericTrait<()> as Gener
|
||||
LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||
--> $DIR/issue-87261.rs:94:5
|
||||
|
|
||||
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
|
||||
@ -231,18 +231,18 @@ LL | accepts_generic_trait(returns_opaque_generic_foo());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
|
||||
found associated type `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated`
|
||||
note: required by a bound in `accepts_generic_trait`
|
||||
--> $DIR/issue-87261.rs:44:46
|
||||
|
|
||||
LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
|
||||
| ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
|
||||
help: consider constraining the associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated` to `()`
|
||||
help: consider constraining the associated type `<impl Foo + GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
|
||||
|
|
||||
LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
|
||||
error[E0271]: type mismatch resolving `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated == ()`
|
||||
--> $DIR/issue-87261.rs:97:5
|
||||
|
|
||||
LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
|
||||
@ -252,8 +252,8 @@ LL | accepts_generic_trait(returns_opaque_generic_duplicate());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
|
||||
= help: consider constraining the associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated` to `()`
|
||||
found associated type `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated`
|
||||
= help: consider constraining the associated type `<impl GenericTrait<u8> + GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||
note: required by a bound in `accepts_generic_trait`
|
||||
--> $DIR/issue-87261.rs:44:46
|
||||
|
@ -15,16 +15,16 @@ fn return_targets_async_block_not_fn() -> u8 {
|
||||
return 0u8;
|
||||
};
|
||||
let _: &dyn Future<Output = ()> = █
|
||||
//~^ ERROR type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
//~^ ERROR type mismatch
|
||||
}
|
||||
|
||||
async fn return_targets_async_block_not_async_fn() -> u8 {
|
||||
//~^ ERROR mismatched types
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
let block = async {
|
||||
return 0u8;
|
||||
};
|
||||
let _: &dyn Future<Output = ()> = █
|
||||
//~^ ERROR type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
//~^ ERROR type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
}
|
||||
|
||||
fn no_break_in_async_block() {
|
||||
|
@ -31,7 +31,7 @@ LL | |
|
||||
LL | | }
|
||||
| |_^ expected `u8`, found `()`
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
||||
|
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
|
||||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
||||
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
||||
|
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
|
@ -46,8 +46,8 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
|
||||
| the expected opaque type
|
||||
| the found opaque type
|
||||
|
|
||||
= note: expected opaque type `impl Future` (`async` closure body)
|
||||
found opaque type `impl Future` (`async` closure body)
|
||||
= note: expected opaque type `impl Future<Output = [async output]>` (`async` closure body)
|
||||
found opaque type `impl Future<Output = [async output]>` (`async` closure body)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
|
||||
LL | spawn(async {
|
||||
| ^^^^^ future created by async block is not `Send`
|
||||
|
|
||||
= help: within `impl Future`, the trait `Send` is not implemented for `*mut ()`
|
||||
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> $DIR/issue-67252-unnamed-future.rs:20:9
|
||||
|
|
||||
|
@ -44,13 +44,13 @@ LL | require_send(send_fut);
|
||||
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
||||
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]`
|
||||
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>`
|
||||
= note: required because it appears within the type `impl Future`
|
||||
= note: required because it appears within the type `impl Future<Output = [async output]>`
|
||||
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
||||
= note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
|
||||
= note: required because it appears within the type `{ResumeTy, impl Future<Output = Arc<RefCell<i32>>>, (), i32, Ready<i32>}`
|
||||
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]`
|
||||
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>`
|
||||
= note: required because it appears within the type `impl Future`
|
||||
= note: required because it appears within the type `impl Future<Output = [async output]>`
|
||||
note: required by a bound in `require_send`
|
||||
--> $DIR/issue-68112.rs:11:25
|
||||
|
|
||||
|
@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
|
||||
LL | assert_send(async {
|
||||
| ^^^^^^^^^^^ future created by async block is not `Send`
|
||||
|
|
||||
= help: within `impl Future`, the trait `Send` is not implemented for `*const u8`
|
||||
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:9
|
||||
|
|
||||
|
9
src/test/ui/attributes/issue-90873.rs
Normal file
9
src/test/ui/attributes/issue-90873.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#![u=||{static d=||1;}]
|
||||
//~^ unexpected token
|
||||
//~| cannot find attribute `u` in this scope
|
||||
//~| `main` function not found in crate `issue_90873`
|
||||
//~| missing type for `static` item
|
||||
|
||||
#![a={impl std::ops::Neg for i8 {}}]
|
||||
//~^ ERROR unexpected token
|
||||
//~| ERROR cannot find attribute `a` in this scope
|
50
src/test/ui/attributes/issue-90873.stderr
Normal file
50
src/test/ui/attributes/issue-90873.stderr
Normal file
@ -0,0 +1,50 @@
|
||||
error: unexpected token: `||
|
||||
{
|
||||
static d: _ = || 1;
|
||||
}`
|
||||
--> $DIR/issue-90873.rs:1:6
|
||||
|
|
||||
LL | #![u=||{static d=||1;}]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unexpected token: `{
|
||||
impl std::ops::Neg for i8 { }
|
||||
}`
|
||||
--> $DIR/issue-90873.rs:7:6
|
||||
|
|
||||
LL | #![a={impl std::ops::Neg for i8 {}}]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `u` in this scope
|
||||
--> $DIR/issue-90873.rs:1:4
|
||||
|
|
||||
LL | #![u=||{static d=||1;}]
|
||||
| ^
|
||||
|
||||
error: cannot find attribute `a` in this scope
|
||||
--> $DIR/issue-90873.rs:7:4
|
||||
|
|
||||
LL | #![a={impl std::ops::Neg for i8 {}}]
|
||||
| ^
|
||||
|
||||
error[E0601]: `main` function not found in crate `issue_90873`
|
||||
--> $DIR/issue-90873.rs:1:1
|
||||
|
|
||||
LL | / #![u=||{static d=||1;}]
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | #![a={impl std::ops::Neg for i8 {}}]
|
||||
| |____________________________________^ consider adding a `main` function to `$DIR/issue-90873.rs`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/issue-90873.rs:1:16
|
||||
|
|
||||
LL | #![u=||{static d=||1;}]
|
||||
| ^ help: provide a type for the item: `d: <type>`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
@ -1,5 +1,5 @@
|
||||
// build-fail
|
||||
// compile-flags: -Zforce-overflow-checks=on
|
||||
// compile-flags: -C overflow-checks=on
|
||||
|
||||
#![allow(arithmetic_overflow)]
|
||||
#![warn(const_err)]
|
||||
|
@ -1,7 +1,5 @@
|
||||
#![l=|x|[b;x ]] //~ ERROR unexpected token: `|x| [b; x]`
|
||||
//~^ ERROR cannot find attribute `l` in this scope
|
||||
//~^^ ERROR attempt to use a non-constant value in a constant [E0435]
|
||||
//~^^^ ERROR cannot find value `b` in this scope [E0425]
|
||||
|
||||
// notice the space at the start,
|
||||
// we can't attach any attributes to this file because it needs to be at the start
|
||||
|
@ -10,21 +10,5 @@ error: cannot find attribute `l` in this scope
|
||||
LL | #![l=|x|[b;x ]]
|
||||
| ^
|
||||
|
||||
error[E0435]: attempt to use a non-constant value in a constant
|
||||
--> $DIR/issue-90878-2.rs:1:13
|
||||
|
|
||||
LL | #![l=|x|[b;x ]]
|
||||
| - ^
|
||||
| |
|
||||
| this would need to be a `const`
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error[E0425]: cannot find value `b` in this scope
|
||||
--> $DIR/issue-90878-2.rs:1:11
|
||||
|
|
||||
LL | #![l=|x|[b;x ]]
|
||||
| ^ help: a local variable with a similar name exists: `x`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0425, E0435.
|
||||
For more information about an error, try `rustc --explain E0425`.
|
||||
|
@ -21,7 +21,7 @@ LL | type MainFn = impl Fn();
|
||||
LL | pub const BAR: MainFn = bar;
|
||||
| ^^^ expected opaque type, found fn item
|
||||
|
|
||||
= note: expected opaque type `impl Fn<()>`
|
||||
= note: expected opaque type `impl Fn()`
|
||||
found fn item `fn() {bar}`
|
||||
|
||||
error: could not find defining uses
|
||||
|
@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
|
||||
--> $DIR/issue-68112.rs:31:9
|
||||
|
|
||||
LL | let _non_send_gen = make_non_send_generator();
|
||||
| ------------- has type `impl Generator` which is not `Send`
|
||||
| ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
|
||||
LL | yield;
|
||||
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
|
||||
LL | };
|
||||
@ -29,9 +29,9 @@ LL | require_send(send_gen);
|
||||
= help: the trait `Sync` is not implemented for `RefCell<i32>`
|
||||
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
|
||||
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]`
|
||||
= note: required because it appears within the type `impl Generator`
|
||||
= note: required because it appears within the type `impl Generator`
|
||||
= note: required because it appears within the type `{impl Generator, ()}`
|
||||
= note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
||||
= note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
|
||||
= note: required because it appears within the type `{impl Generator<Return = Arc<RefCell<i32>>>, ()}`
|
||||
= note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]`
|
||||
note: required by a bound in `require_send`
|
||||
--> $DIR/issue-68112.rs:22:25
|
||||
|
@ -2,16 +2,16 @@ error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||
--> $DIR/auto-trait-leak2.rs:13:10
|
||||
|
|
||||
LL | fn before() -> impl Fn(i32) {
|
||||
| ------------ within this `impl Fn<(i32,)>`
|
||||
| ------------ within this `impl Fn(i32)`
|
||||
...
|
||||
LL | send(before());
|
||||
| ---- ^^^^^^^^ `Rc<Cell<i32>>` cannot be sent between threads safely
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]`
|
||||
= note: required because it appears within the type `impl Fn<(i32,)>`
|
||||
= note: required because it appears within the type `impl Fn(i32)`
|
||||
note: required by a bound in `send`
|
||||
--> $DIR/auto-trait-leak2.rs:10:12
|
||||
|
|
||||
@ -27,11 +27,11 @@ LL | send(after());
|
||||
| required by a bound introduced by this call
|
||||
...
|
||||
LL | fn after() -> impl Fn(i32) {
|
||||
| ------------ within this `impl Fn<(i32,)>`
|
||||
| ------------ within this `impl Fn(i32)`
|
||||
|
|
||||
= help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
|
||||
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]`
|
||||
= note: required because it appears within the type `impl Fn<(i32,)>`
|
||||
= note: required because it appears within the type `impl Fn(i32)`
|
||||
note: required by a bound in `send`
|
||||
--> $DIR/auto-trait-leak2.rs:10:12
|
||||
|
|
||||
|
@ -13,7 +13,7 @@ impl<S> Bar for S {
|
||||
type E = impl std::marker::Copy;
|
||||
fn foo<T>() -> Self::E {
|
||||
//~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
//~| ERROR the trait bound `impl Future: Copy` is not satisfied [E0277]
|
||||
//~| ERROR the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
|
||||
async {}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the trait bound `impl Future: Copy` is not satisfied
|
||||
error[E0277]: the trait bound `impl Future<Output = [async output]>: Copy` is not satisfied
|
||||
--> $DIR/issue-55872-2.rs:14:20
|
||||
|
|
||||
LL | fn foo<T>() -> Self::E {
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `impl Future`
|
||||
| ^^^^^^^ the trait `Copy` is not implemented for `impl Future<Output = [async output]>`
|
||||
|
||||
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
--> $DIR/issue-55872-2.rs:14:28
|
||||
|
@ -19,14 +19,14 @@ LL |
|
||||
LL | lint_files().flat_map(|f| gather_from_file(&f))
|
||||
| -----------------------------------------------
|
||||
| |
|
||||
| returning here with type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
| returning here with type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
| returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
| returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
...
|
||||
LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint> {
|
||||
| -------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
| -------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
...
|
||||
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
|
||||
| -------------------------------------- returning this opaque type `FlatMap<impl Iterator, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
| -------------------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -17,10 +17,10 @@ LL | fn foo() -> impl Fn() {
|
||||
| ^^^^^^^^^ recursive opaque type
|
||||
...
|
||||
LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
|
||||
| ----------------------------------------------- returning here with type `impl Fn<()>`
|
||||
| ----------------------------------------------- returning here with type `impl Fn()`
|
||||
...
|
||||
LL | fn wrap(f: impl Fn()) -> impl Fn() {
|
||||
| --------- returning this opaque type `impl Fn<()>`
|
||||
| --------- returning this opaque type `impl Fn()`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
@ -15,7 +15,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
|
||||
| ------------------------------- the found opaque type
|
||||
|
|
||||
= note: expected opaque type `impl Future<Output = u8>`
|
||||
found opaque type `impl Future`
|
||||
found opaque type `impl Future<Output = [async output]>`
|
||||
= note: distinct uses of `impl Trait` result in different opaque types
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -19,5 +19,5 @@ fn main() {
|
||||
let g = |(a, _)| a;
|
||||
let t7 = |env| |a| |b| t7p(f, g)(((env, a), b));
|
||||
let t8 = t8n(t7, t7p(f, g));
|
||||
//~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>
|
||||
//~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` [E0277]
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>`
|
||||
error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
|
||||
--> $DIR/issue-59494.rs:21:22
|
||||
|
|
||||
LL | let t8 = t8n(t7, t7p(f, g));
|
||||
| --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>`
|
||||
| --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>`
|
||||
= help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))`
|
||||
note: required by a bound in `t8n`
|
||||
--> $DIR/issue-59494.rs:5:45
|
||||
|
|
||||
|
@ -33,7 +33,7 @@ fn use_of_b() -> AliasB {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `impl TraitA`
|
||||
pub fn lint_me() -> <AliasB as TraitB>::Assoc; //~ ERROR: uses type `impl TraitA<Assoc = u32>`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: `extern` block uses type `impl TraitA`, which is not FFI-safe
|
||||
error: `extern` block uses type `impl TraitA<Assoc = u32>`, which is not FFI-safe
|
||||
--> $DIR/lint-ctypes-73251-2.rs:36:25
|
||||
|
|
||||
LL | pub fn lint_me() -> <AliasB as TraitB>::Assoc;
|
||||
|
@ -9,7 +9,7 @@ pub fn ret_closure() -> A {
|
||||
|
||||
extern "C" {
|
||||
pub fn a(_: A);
|
||||
//~^ ERROR `extern` block uses type `impl Fn<()>`, which is not FFI-safe
|
||||
//~^ ERROR `extern` block uses type `impl Fn()`, which is not FFI-safe [improper_ctypes]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: `extern` block uses type `impl Fn<()>`, which is not FFI-safe
|
||||
error: `extern` block uses type `impl Fn()`, which is not FFI-safe
|
||||
--> $DIR/opaque-ty-ffi-unsafe.rs:11:17
|
||||
|
|
||||
LL | pub fn a(_: A);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-pass
|
||||
// compile-flags: -Z force-overflow-checks=off
|
||||
// compile-flags: -C overflow-checks=off
|
||||
|
||||
// Test that with MIR codegen, overflow checks can be
|
||||
// turned off, even when they're from core::ops::*.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-pass
|
||||
// compile-flags: -Z force-overflow-checks=on
|
||||
// compile-flags: -C overflow-checks=on
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
use std::thread;
|
||||
|
@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:22]` cannot be used
|
||||
LL | const { || {} } => {},
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: `impl Future` cannot be used in patterns
|
||||
error: `impl Future<Output = [async output]>` cannot be used in patterns
|
||||
--> $DIR/non-structural-match-types.rs:12:9
|
||||
|
|
||||
LL | const { async {} } => {},
|
||||
|
20
src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs
Normal file
20
src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
|
||||
const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Drop {
|
||||
match res {
|
||||
Ok(t) => Some(t),
|
||||
Err(_e) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Foo<T>(T);
|
||||
|
||||
const fn baz<T: ~const Drop, E: ~const Drop>(res: Result<Foo<T>, Foo<E>>) -> Option<Foo<T>> {
|
||||
foo(res)
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,51 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![feature(const_t_try)]
|
||||
#![feature(const_try)]
|
||||
#![feature(try_trait_v2)]
|
||||
|
||||
#![stable(feature = "foo", since = "1.0")]
|
||||
|
||||
use std::ops::{ControlFlow, FromResidual, Try};
|
||||
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
pub struct T;
|
||||
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
#[rustc_const_unstable(feature = "const_t_try", issue = "none")]
|
||||
impl const Try for T {
|
||||
type Output = T;
|
||||
type Residual = T;
|
||||
|
||||
fn from_output(t: T) -> T {
|
||||
t
|
||||
}
|
||||
|
||||
fn branch(self) -> ControlFlow<T, T> {
|
||||
ControlFlow::Continue(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
#[rustc_const_unstable(feature = "const_t_try", issue = "none")]
|
||||
impl const FromResidual for T {
|
||||
fn from_residual(t: T) -> T {
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
pub trait Tr {
|
||||
#[default_method_body_is_const]
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
fn bar() -> T {
|
||||
T?
|
||||
// Should be allowed.
|
||||
// Must enable unstable features to call this trait fn in const contexts.
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -81,7 +81,7 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
|
||||
| ------------------------------- the found opaque type
|
||||
|
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
|
||||
found opaque type `impl Future`
|
||||
found opaque type `impl Future<Output = [async output]>`
|
||||
help: you need to pin and box this expression
|
||||
|
|
||||
LL ~ Box::pin(async {
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied
|
||||
error[E0277]: the trait bound `fn() -> impl T<O = ()> {foo}: T` is not satisfied
|
||||
--> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
|
||||
|
|
||||
LL | fn foo() -> impl T<O=()> { S }
|
||||
| --- consider calling this function
|
||||
...
|
||||
LL | bar(foo);
|
||||
| --- ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
|
||||
| --- ^^^ the trait `T` is not implemented for `fn() -> impl T<O = ()> {foo}`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
|
@ -5,7 +5,7 @@
|
||||
use std::future::Future;
|
||||
|
||||
type G<'a, T> = impl Future<Output = ()>;
|
||||
//~^ ERROR: type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
//~^ ERROR: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
//~| ERROR: the trait bound `T: Trait` is not satisfied
|
||||
|
||||
trait Trait {
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0271]: type mismatch resolving `<impl Future as Future>::Output == ()`
|
||||
error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
--> $DIR/issue-89686.rs:7:17
|
||||
|
|
||||
LL | type G<'a, T> = impl Future<Output = ()>;
|
||||
@ -13,8 +13,8 @@ LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
|
||||
| ------------------------------- the found opaque type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl Future as Future>::Output`
|
||||
= help: consider constraining the associated type `<impl Future as Future>::Output` to `()`
|
||||
found associated type `<impl Future<Output = [async output]> as Future>::Output`
|
||||
= help: consider constraining the associated type `<impl Future<Output = [async output]> as Future>::Output` to `()`
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||
|
||||
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||
|
Loading…
Reference in New Issue
Block a user