Auto merge of #136549 - matthiaskrgr:rollup-sqbpgtd, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #136242 (Remove `LateContext::match_def_path()`) - #136274 (Check Sizedness of return type in WF) - #136284 (Allow using named consts in pattern types) - #136477 (Fix a couple NLL TLS spans ) - #136497 (Report generic mismatches when calling bodyless trait functions) - #136520 (Remove unnecessary layout assertions for object-safe receivers) - #136526 (mir_build: Rename `thir::cx::Cx` to `ThirBuildCx` and remove `UserAnnotatedTyHelpers`) Failed merges: - #136304 (Reject negative literals for unsigned or char types in pattern ranges and literals) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
bef3c3b01f
118 changed files with 1472 additions and 1166 deletions
|
@ -412,8 +412,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
|
fn visit_pattern_type_pattern(&mut self, pat: &'hir hir::TyPat<'hir>) {
|
||||||
self.visit_pat(p)
|
self.insert(pat.span, pat.hir_id, Node::TyPat(pat));
|
||||||
|
|
||||||
|
self.with_parent(pat.hir_id, |this| {
|
||||||
|
intravisit::walk_ty_pat(this, pat);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_precise_capturing_arg(
|
fn visit_precise_capturing_arg(
|
||||||
|
|
|
@ -1377,7 +1377,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
|
TyKind::Pat(ty, pat) => {
|
||||||
|
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
|
||||||
|
}
|
||||||
TyKind::MacCall(_) => {
|
TyKind::MacCall(_) => {
|
||||||
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_span::source_map::{Spanned, respan};
|
use rustc_span::source_map::{Spanned, respan};
|
||||||
use rustc_span::{Ident, Span};
|
use rustc_span::{Ident, Span, kw};
|
||||||
|
|
||||||
use super::errors::{
|
use super::errors::{
|
||||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||||
|
@ -429,4 +429,81 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
};
|
};
|
||||||
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
|
||||||
|
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
|
||||||
|
// loop here to avoid recursion
|
||||||
|
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||||
|
let node = loop {
|
||||||
|
match &pattern.kind {
|
||||||
|
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
||||||
|
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
|
||||||
|
// That requires first modifying the AST to have const args here.
|
||||||
|
let mut lower_expr = |e: &Expr| -> &_ {
|
||||||
|
if let ExprKind::Path(None, path) = &e.kind
|
||||||
|
&& let Some(res) = self
|
||||||
|
.resolver
|
||||||
|
.get_partial_res(e.id)
|
||||||
|
.and_then(|partial_res| partial_res.full_res())
|
||||||
|
{
|
||||||
|
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
|
||||||
|
} else {
|
||||||
|
let node_id = self.next_node_id();
|
||||||
|
let def_id = self.create_def(
|
||||||
|
self.current_hir_id_owner.def_id,
|
||||||
|
node_id,
|
||||||
|
kw::Empty,
|
||||||
|
DefKind::AnonConst,
|
||||||
|
e.span,
|
||||||
|
);
|
||||||
|
let hir_id = self.lower_node_id(node_id);
|
||||||
|
let ac = self.arena.alloc(hir::AnonConst {
|
||||||
|
def_id,
|
||||||
|
hir_id,
|
||||||
|
body: self.lower_const_body(pattern.span, Some(e)),
|
||||||
|
span: self.lower_span(pattern.span),
|
||||||
|
});
|
||||||
|
self.arena.alloc(hir::ConstArg {
|
||||||
|
hir_id: self.next_id(),
|
||||||
|
kind: hir::ConstArgKind::Anon(ac),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break hir::TyPatKind::Range(
|
||||||
|
e1.as_deref().map(|e| lower_expr(e)),
|
||||||
|
e2.as_deref().map(|e| lower_expr(e)),
|
||||||
|
self.lower_range_end(end, e2.is_some()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// return inner to be processed in next loop
|
||||||
|
PatKind::Paren(inner) => pattern = inner,
|
||||||
|
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||||
|
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
|
||||||
|
PatKind::Deref(..)
|
||||||
|
| PatKind::Box(..)
|
||||||
|
| PatKind::Or(..)
|
||||||
|
| PatKind::Struct(..)
|
||||||
|
| PatKind::TupleStruct(..)
|
||||||
|
| PatKind::Tuple(..)
|
||||||
|
| PatKind::Ref(..)
|
||||||
|
| PatKind::Expr(..)
|
||||||
|
| PatKind::Guard(..)
|
||||||
|
| PatKind::Slice(_)
|
||||||
|
| PatKind::Ident(..)
|
||||||
|
| PatKind::Path(..)
|
||||||
|
| PatKind::Wild
|
||||||
|
| PatKind::Never
|
||||||
|
| PatKind::Rest => {
|
||||||
|
break hir::TyPatKind::Err(
|
||||||
|
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3112,12 +3112,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
drop_span, borrow_span
|
drop_span, borrow_span
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// `TerminatorKind::Return`'s span (the `drop_span` here) `lo` can be subtly wrong and point
|
||||||
|
// at a single character after the end of the function. This is somehow relied upon in
|
||||||
|
// existing diagnostics, and changing this in `rustc_mir_build` makes diagnostics worse in
|
||||||
|
// general. We fix these here.
|
||||||
|
let sm = self.infcx.tcx.sess.source_map();
|
||||||
|
let end_of_function = if drop_span.is_empty()
|
||||||
|
&& let Ok(adjusted_span) = sm.span_extend_prev_while(drop_span, |c| c == '}')
|
||||||
|
{
|
||||||
|
adjusted_span
|
||||||
|
} else {
|
||||||
|
drop_span
|
||||||
|
};
|
||||||
self.thread_local_value_does_not_live_long_enough(borrow_span)
|
self.thread_local_value_does_not_live_long_enough(borrow_span)
|
||||||
.with_span_label(
|
.with_span_label(
|
||||||
borrow_span,
|
borrow_span,
|
||||||
"thread-local variables cannot be borrowed beyond the end of the function",
|
"thread-local variables cannot be borrowed beyond the end of the function",
|
||||||
)
|
)
|
||||||
.with_span_label(drop_span, "end of enclosing function is here")
|
.with_span_label(end_of_function, "end of enclosing function is here")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
|
|
@ -101,6 +101,10 @@ impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> {
|
||||||
s.s.space();
|
s.s.space();
|
||||||
s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
|
s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
|
||||||
}
|
}
|
||||||
|
pprust_hir::AnnNode::TyPat(pat) => {
|
||||||
|
s.s.space();
|
||||||
|
s.synth_comment(format!("ty pat hir_id: {}", pat.hir_id));
|
||||||
|
}
|
||||||
pprust_hir::AnnNode::Arm(arm) => {
|
pprust_hir::AnnNode::Arm(arm) => {
|
||||||
s.s.space();
|
s.s.space();
|
||||||
s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
|
s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
|
||||||
|
|
|
@ -1418,6 +1418,14 @@ impl<'hir> Block<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
pub struct TyPat<'hir> {
|
||||||
|
#[stable_hasher(ignore)]
|
||||||
|
pub hir_id: HirId,
|
||||||
|
pub kind: TyPatKind<'hir>,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct Pat<'hir> {
|
pub struct Pat<'hir> {
|
||||||
#[stable_hasher(ignore)]
|
#[stable_hasher(ignore)]
|
||||||
|
@ -1591,6 +1599,15 @@ pub enum PatExprKind<'hir> {
|
||||||
Path(QPath<'hir>),
|
Path(QPath<'hir>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
pub enum TyPatKind<'hir> {
|
||||||
|
/// A range pattern (e.g., `1..=2` or `1..2`).
|
||||||
|
Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
|
||||||
|
|
||||||
|
/// A placeholder for a pattern that wasn't well formed in some way.
|
||||||
|
Err(ErrorGuaranteed),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum PatKind<'hir> {
|
pub enum PatKind<'hir> {
|
||||||
/// Represents a wildcard pattern (i.e., `_`).
|
/// Represents a wildcard pattern (i.e., `_`).
|
||||||
|
@ -3384,7 +3401,7 @@ pub enum TyKind<'hir, Unambig = ()> {
|
||||||
/// Placeholder for a type that has failed to be defined.
|
/// Placeholder for a type that has failed to be defined.
|
||||||
Err(rustc_span::ErrorGuaranteed),
|
Err(rustc_span::ErrorGuaranteed),
|
||||||
/// Pattern types (`pattern_type!(u32 is 1..)`)
|
/// Pattern types (`pattern_type!(u32 is 1..)`)
|
||||||
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
|
Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
|
||||||
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
||||||
/// specified. This can appear anywhere in a type.
|
/// specified. This can appear anywhere in a type.
|
||||||
///
|
///
|
||||||
|
@ -4370,6 +4387,7 @@ pub enum Node<'hir> {
|
||||||
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
|
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
|
||||||
TraitRef(&'hir TraitRef<'hir>),
|
TraitRef(&'hir TraitRef<'hir>),
|
||||||
OpaqueTy(&'hir OpaqueTy<'hir>),
|
OpaqueTy(&'hir OpaqueTy<'hir>),
|
||||||
|
TyPat(&'hir TyPat<'hir>),
|
||||||
Pat(&'hir Pat<'hir>),
|
Pat(&'hir Pat<'hir>),
|
||||||
PatField(&'hir PatField<'hir>),
|
PatField(&'hir PatField<'hir>),
|
||||||
/// Needed as its own node with its own HirId for tracking
|
/// Needed as its own node with its own HirId for tracking
|
||||||
|
@ -4432,6 +4450,7 @@ impl<'hir> Node<'hir> {
|
||||||
| Node::Block(..)
|
| Node::Block(..)
|
||||||
| Node::Ctor(..)
|
| Node::Ctor(..)
|
||||||
| Node::Pat(..)
|
| Node::Pat(..)
|
||||||
|
| Node::TyPat(..)
|
||||||
| Node::PatExpr(..)
|
| Node::PatExpr(..)
|
||||||
| Node::Arm(..)
|
| Node::Arm(..)
|
||||||
| Node::LetStmt(..)
|
| Node::LetStmt(..)
|
||||||
|
|
|
@ -393,10 +393,8 @@ pub trait Visitor<'v>: Sized {
|
||||||
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
|
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
|
||||||
walk_expr_field(self, field)
|
walk_expr_field(self, field)
|
||||||
}
|
}
|
||||||
fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
|
||||||
// Do nothing. Only a few visitors need to know the details of the pattern type,
|
walk_ty_pat(self, p)
|
||||||
// and they opt into it. All other visitors will just choke on our fake patterns
|
|
||||||
// because they aren't in a body.
|
|
||||||
}
|
}
|
||||||
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
|
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
|
||||||
walk_generic_param(self, p)
|
walk_generic_param(self, p)
|
||||||
|
@ -702,6 +700,18 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
|
||||||
visitor.visit_expr(arm.body)
|
visitor.visit_expr(arm.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
|
||||||
|
try_visit!(visitor.visit_id(pattern.hir_id));
|
||||||
|
match pattern.kind {
|
||||||
|
TyPatKind::Range(lower_bound, upper_bound, _) => {
|
||||||
|
visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
|
||||||
|
visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => (),
|
||||||
|
}
|
||||||
|
V::Result::output()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
|
||||||
try_visit!(visitor.visit_id(pattern.hir_id));
|
try_visit!(visitor.visit_id(pattern.hir_id));
|
||||||
match pattern.kind {
|
match pattern.kind {
|
||||||
|
|
|
@ -436,9 +436,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
|
||||||
hir_analysis_parenthesized_fn_trait_expansion =
|
hir_analysis_parenthesized_fn_trait_expansion =
|
||||||
parenthesized trait syntax expands to `{$expanded_type}`
|
parenthesized trait syntax expands to `{$expanded_type}`
|
||||||
|
|
||||||
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
|
|
||||||
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
|
|
||||||
.label = this type is the same as the inner type without a pattern
|
|
||||||
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
||||||
.label = not allowed in type signatures
|
.label = not allowed in type signatures
|
||||||
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
||||||
|
|
|
@ -1065,6 +1065,7 @@ fn check_associated_item(
|
||||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
|
check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn => {
|
ty::AssocKind::Fn => {
|
||||||
|
@ -1189,7 +1190,7 @@ fn check_type_defn<'tcx>(
|
||||||
),
|
),
|
||||||
wfcx.param_env,
|
wfcx.param_env,
|
||||||
ty,
|
ty,
|
||||||
tcx.require_lang_item(LangItem::Sized, None),
|
tcx.require_lang_item(LangItem::Sized, Some(hir_ty.span)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1315,7 @@ fn check_item_type(
|
||||||
),
|
),
|
||||||
wfcx.param_env,
|
wfcx.param_env,
|
||||||
item_ty,
|
item_ty,
|
||||||
tcx.require_lang_item(LangItem::Sized, None),
|
tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1644,6 +1645,31 @@ fn check_fn_or_method<'tcx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the function has a body, additionally require that the return type is sized.
|
||||||
|
check_sized_if_body(wfcx, def_id, sig.output(), match hir_decl.output {
|
||||||
|
hir::FnRetTy::Return(ty) => Some(ty.span),
|
||||||
|
hir::FnRetTy::DefaultReturn(_) => None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_sized_if_body<'tcx>(
|
||||||
|
wfcx: &WfCheckingCtxt<'_, 'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
maybe_span: Option<Span>,
|
||||||
|
) {
|
||||||
|
let tcx = wfcx.tcx();
|
||||||
|
if let Some(body) = tcx.hir().maybe_body_owned_by(def_id) {
|
||||||
|
let span = maybe_span.unwrap_or(body.value.span);
|
||||||
|
|
||||||
|
wfcx.register_bound(
|
||||||
|
ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
|
||||||
|
wfcx.param_env,
|
||||||
|
ty,
|
||||||
|
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
|
/// The `arbitrary_self_types_pointers` feature implies `arbitrary_self_types`.
|
||||||
|
|
|
@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
{
|
{
|
||||||
Some(parent_did)
|
Some(parent_did)
|
||||||
}
|
}
|
||||||
|
Node::TyPat(_) => Some(parent_did),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) {
|
||||||
intravisit::walk_pat(self, p)
|
intravisit::walk_ty_pat(self, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
|
|
@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer;
|
||||||
|
|
||||||
mod opaque;
|
mod opaque;
|
||||||
|
|
||||||
fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
use hir::*;
|
use hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
let tcx = icx.tcx;
|
||||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||||
|
|
||||||
let node = tcx.hir_node(hir_id);
|
let node = tcx.hir_node(hir_id);
|
||||||
|
@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
hir_id: arg_hir_id,
|
hir_id: arg_hir_id,
|
||||||
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
||||||
..
|
..
|
||||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span),
|
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
|
||||||
|
|
||||||
// Anon consts outside the type system.
|
// Anon consts outside the type system.
|
||||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||||
|
@ -138,10 +139,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||||
use hir::*;
|
use hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
|
let tcx = icx.tcx;
|
||||||
|
|
||||||
match tcx.parent_hir_node(arg_hir_id) {
|
match tcx.parent_hir_node(arg_hir_id) {
|
||||||
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
||||||
// generic parameter definition.
|
// generic parameter definition.
|
||||||
|
@ -149,7 +152,15 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span
|
||||||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||||
if constant.hir_id == arg_hir_id =>
|
if constant.hir_id == arg_hir_id =>
|
||||||
{
|
{
|
||||||
return tcx.types.usize;
|
tcx.types.usize
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::TyPat(pat) => {
|
||||||
|
let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
|
||||||
|
bug!()
|
||||||
|
};
|
||||||
|
assert_eq!(p.hir_id, pat.hir_id);
|
||||||
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
||||||
|
@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||||
tcx.typeck(def_id).node_type(hir_id)
|
tcx.typeck(def_id).node_type(hir_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
Node::AnonConst(_) => anon_const_type_of(&icx, def_id),
|
||||||
|
|
||||||
Node::ConstBlock(_) => {
|
Node::ConstBlock(_) => {
|
||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||||
|
|
|
@ -1605,13 +1605,6 @@ pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
||||||
pub bad_place: &'static str,
|
pub bad_place: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_pattern_type_non_const_range)]
|
|
||||||
pub(crate) struct NonConstRange {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub(crate) enum InvalidReceiverTyHint {
|
pub(crate) enum InvalidReceiverTyHint {
|
||||||
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
|
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
|
||||||
|
|
|
@ -2,13 +2,6 @@ use rustc_macros::Diagnostic;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_pattern_type_wild_pat)]
|
|
||||||
pub(crate) struct WildPatTy {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_invalid_base_type)]
|
#[diag(hir_analysis_invalid_base_type)]
|
||||||
pub(crate) struct InvalidBaseType<'tcx> {
|
pub(crate) struct InvalidBaseType<'tcx> {
|
||||||
|
|
|
@ -53,7 +53,7 @@ use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::check::check_abi_fn_ptr;
|
use crate::check::check_abi_fn_ptr;
|
||||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, WildPatTy};
|
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType};
|
||||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
||||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||||
use crate::middle::resolve_bound_vars as rbv;
|
use crate::middle::resolve_bound_vars as rbv;
|
||||||
|
@ -2435,11 +2435,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let ty_span = ty.span;
|
let ty_span = ty.span;
|
||||||
let ty = self.lower_ty(ty);
|
let ty = self.lower_ty(ty);
|
||||||
let pat_ty = match pat.kind {
|
let pat_ty = match pat.kind {
|
||||||
hir::PatKind::Wild => {
|
hir::TyPatKind::Range(start, end, include_end) => {
|
||||||
let err = self.dcx().emit_err(WildPatTy { span: pat.span });
|
|
||||||
Ty::new_error(tcx, err)
|
|
||||||
}
|
|
||||||
hir::PatKind::Range(start, end, include_end) => {
|
|
||||||
let ty = match ty.kind() {
|
let ty = match ty.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
||||||
_ => Ty::new_error(
|
_ => Ty::new_error(
|
||||||
|
@ -2452,54 +2448,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
|
let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||||
let (c, c_ty) = match expr.kind {
|
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||||
hir::PatExprKind::Lit { lit, negated } => {
|
|
||||||
let lit_input =
|
|
||||||
LitToConstInput { lit: &lit.node, ty, neg: negated };
|
|
||||||
let ct = tcx.lit_to_const(lit_input);
|
|
||||||
(ct, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::PatExprKind::Path(hir::QPath::Resolved(
|
|
||||||
_,
|
|
||||||
path @ &hir::Path {
|
|
||||||
res: Res::Def(DefKind::ConstParam, def_id),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
)) => {
|
|
||||||
match self.prohibit_generic_args(
|
|
||||||
path.segments.iter(),
|
|
||||||
GenericsArgsErrExtend::Param(def_id),
|
|
||||||
) {
|
|
||||||
Ok(()) => {
|
|
||||||
let ty = tcx
|
|
||||||
.type_of(def_id)
|
|
||||||
.no_bound_vars()
|
|
||||||
.expect("const parameter types cannot be generic");
|
|
||||||
let ct = self.lower_const_param(def_id, expr.hir_id);
|
|
||||||
(ct, ty)
|
|
||||||
}
|
|
||||||
Err(guar) => (
|
|
||||||
ty::Const::new_error(tcx, guar),
|
|
||||||
Ty::new_error(tcx, guar),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let err = tcx
|
|
||||||
.dcx()
|
|
||||||
.emit_err(crate::errors::NonConstRange { span: expr.span });
|
|
||||||
(ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.record_ty(expr.hir_id, c_ty, expr.span);
|
|
||||||
c
|
|
||||||
};
|
|
||||||
|
|
||||||
let start = start.map(expr_to_const);
|
|
||||||
let end = end.map(expr_to_const);
|
|
||||||
|
|
||||||
let include_end = match include_end {
|
let include_end = match include_end {
|
||||||
hir::RangeEnd::Included => true,
|
hir::RangeEnd::Included => true,
|
||||||
|
@ -2509,12 +2459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
||||||
Ty::new_pat(tcx, ty, pat)
|
Ty::new_pat(tcx, ty, pat)
|
||||||
}
|
}
|
||||||
hir::PatKind::Err(e) => Ty::new_error(tcx, e),
|
hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
|
||||||
_ => Ty::new_error_with_message(
|
|
||||||
tcx,
|
|
||||||
pat.span,
|
|
||||||
format!("unsupported pattern for pattern type: {pat:#?}"),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
self.record_ty(pat.hir_id, ty, pat.span);
|
self.record_ty(pat.hir_id, ty, pat.span);
|
||||||
pat_ty
|
pat_ty
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc_ast_pretty::pprust::state::MacHeader;
|
||||||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
|
BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
|
||||||
HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
|
HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TyPatKind,
|
||||||
};
|
};
|
||||||
use rustc_span::source_map::SourceMap;
|
use rustc_span::source_map::SourceMap;
|
||||||
use rustc_span::{FileName, Ident, Span, Symbol, kw};
|
use rustc_span::{FileName, Ident, Span, Symbol, kw};
|
||||||
|
@ -35,6 +35,7 @@ pub enum AnnNode<'a> {
|
||||||
SubItem(HirId),
|
SubItem(HirId),
|
||||||
Expr(&'a hir::Expr<'a>),
|
Expr(&'a hir::Expr<'a>),
|
||||||
Pat(&'a hir::Pat<'a>),
|
Pat(&'a hir::Pat<'a>),
|
||||||
|
TyPat(&'a hir::TyPat<'a>),
|
||||||
Arm(&'a hir::Arm<'a>),
|
Arm(&'a hir::Arm<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +199,7 @@ impl<'a> State<'a> {
|
||||||
Node::TraitRef(a) => self.print_trait_ref(a),
|
Node::TraitRef(a) => self.print_trait_ref(a),
|
||||||
Node::OpaqueTy(o) => self.print_opaque_ty(o),
|
Node::OpaqueTy(o) => self.print_opaque_ty(o),
|
||||||
Node::Pat(a) => self.print_pat(a),
|
Node::Pat(a) => self.print_pat(a),
|
||||||
|
Node::TyPat(a) => self.print_ty_pat(a),
|
||||||
Node::PatField(a) => self.print_patfield(a),
|
Node::PatField(a) => self.print_patfield(a),
|
||||||
Node::PatExpr(a) => self.print_pat_expr(a),
|
Node::PatExpr(a) => self.print_pat_expr(a),
|
||||||
Node::Arm(a) => self.print_arm(a),
|
Node::Arm(a) => self.print_arm(a),
|
||||||
|
@ -224,6 +226,16 @@ impl<'a> State<'a> {
|
||||||
Node::Err(_) => self.word("/*ERROR*/"),
|
Node::Err(_) => self.word("/*ERROR*/"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_generic_arg(&mut self, generic_arg: &GenericArg<'_>, elide_lifetimes: bool) {
|
||||||
|
match generic_arg {
|
||||||
|
GenericArg::Lifetime(lt) if !elide_lifetimes => self.print_lifetime(lt),
|
||||||
|
GenericArg::Lifetime(_) => {}
|
||||||
|
GenericArg::Type(ty) => self.print_type(ty.as_unambig_ty()),
|
||||||
|
GenericArg::Const(ct) => self.print_const_arg(ct.as_unambig_ct()),
|
||||||
|
GenericArg::Infer(_inf) => self.word("_"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for State<'_> {
|
impl std::ops::Deref for State<'_> {
|
||||||
|
@ -448,7 +460,7 @@ impl<'a> State<'a> {
|
||||||
hir::TyKind::Pat(ty, pat) => {
|
hir::TyKind::Pat(ty, pat) => {
|
||||||
self.print_type(ty);
|
self.print_type(ty);
|
||||||
self.word(" is ");
|
self.word(" is ");
|
||||||
self.print_pat(pat);
|
self.print_ty_pat(pat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.end()
|
self.end()
|
||||||
|
@ -1797,13 +1809,7 @@ impl<'a> State<'a> {
|
||||||
if nonelided_generic_args {
|
if nonelided_generic_args {
|
||||||
start_or_comma(self);
|
start_or_comma(self);
|
||||||
self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
|
self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
|
||||||
match generic_arg {
|
s.print_generic_arg(generic_arg, elide_lifetimes)
|
||||||
GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
|
|
||||||
GenericArg::Lifetime(_) => {}
|
|
||||||
GenericArg::Type(ty) => s.print_type(ty.as_unambig_ty()),
|
|
||||||
GenericArg::Const(ct) => s.print_const_arg(ct.as_unambig_ct()),
|
|
||||||
GenericArg::Infer(_inf) => s.word("_"),
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1864,6 +1870,33 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_ty_pat(&mut self, pat: &hir::TyPat<'_>) {
|
||||||
|
self.maybe_print_comment(pat.span.lo());
|
||||||
|
self.ann.pre(self, AnnNode::TyPat(pat));
|
||||||
|
// Pat isn't normalized, but the beauty of it
|
||||||
|
// is that it doesn't matter
|
||||||
|
match pat.kind {
|
||||||
|
TyPatKind::Range(begin, end, end_kind) => {
|
||||||
|
if let Some(expr) = begin {
|
||||||
|
self.print_const_arg(expr);
|
||||||
|
}
|
||||||
|
match end_kind {
|
||||||
|
RangeEnd::Included => self.word("..."),
|
||||||
|
RangeEnd::Excluded => self.word(".."),
|
||||||
|
}
|
||||||
|
if let Some(expr) = end {
|
||||||
|
self.print_const_arg(expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {
|
||||||
|
self.popen();
|
||||||
|
self.word("/*ERROR*/");
|
||||||
|
self.pclose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.ann.post(self, AnnNode::TyPat(pat))
|
||||||
|
}
|
||||||
|
|
||||||
fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||||
self.maybe_print_comment(pat.span.lo());
|
self.maybe_print_comment(pat.span.lo());
|
||||||
self.ann.pre(self, AnnNode::Pat(pat));
|
self.ann.pre(self, AnnNode::Pat(pat));
|
||||||
|
|
|
@ -117,22 +117,17 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||||
|
|
||||||
fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
|
fcx.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
|
||||||
|
|
||||||
let return_or_body_span = match decl.output {
|
// We checked the root's ret ty during wfcheck, but not the child.
|
||||||
hir::FnRetTy::DefaultReturn(_) => body.value.span,
|
|
||||||
hir::FnRetTy::Return(ty) => ty.span,
|
|
||||||
};
|
|
||||||
|
|
||||||
fcx.require_type_is_sized(
|
|
||||||
declared_ret_ty,
|
|
||||||
return_or_body_span,
|
|
||||||
ObligationCauseCode::SizedReturnType,
|
|
||||||
);
|
|
||||||
// We checked the root's signature during wfcheck, but not the child.
|
|
||||||
if fcx.tcx.is_typeck_child(fn_def_id.to_def_id()) {
|
if fcx.tcx.is_typeck_child(fn_def_id.to_def_id()) {
|
||||||
|
let return_or_body_span = match decl.output {
|
||||||
|
hir::FnRetTy::DefaultReturn(_) => body.value.span,
|
||||||
|
hir::FnRetTy::Return(ty) => ty.span,
|
||||||
|
};
|
||||||
|
|
||||||
fcx.require_type_is_sized(
|
fcx.require_type_is_sized(
|
||||||
declared_ret_ty,
|
declared_ret_ty,
|
||||||
return_or_body_span,
|
return_or_body_span,
|
||||||
ObligationCauseCode::WellFormed(None),
|
ObligationCauseCode::SizedReturnType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -412,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
|
||||||
|
|
||||||
hir::Node::Pat(_) => {
|
hir::Node::TyPat(_) | hir::Node::Pat(_) => {
|
||||||
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
|
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_hir::{ExprKind, HirId, Node, QPath};
|
||||||
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt;
|
||||||
use rustc_hir_analysis::check::potentially_plural_count;
|
use rustc_hir_analysis::check::potentially_plural_count;
|
||||||
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::{Idx, IndexVec};
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TypeTrace};
|
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, TypeTrace};
|
||||||
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
use rustc_middle::ty::adjustment::AllowTwoPhase;
|
||||||
use rustc_middle::ty::error::TypeError;
|
use rustc_middle::ty::error::TypeError;
|
||||||
|
@ -21,7 +21,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
|
||||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
|
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
|
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
|
||||||
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
|
use rustc_trait_selection::error_reporting::infer::{FailureCode, ObligationCauseExt};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
use rustc_trait_selection::infer::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
|
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext};
|
||||||
|
@ -126,7 +126,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Err(guar) => Err(guar),
|
Err(guar) => Err(guar),
|
||||||
};
|
};
|
||||||
if let Err(guar) = has_error {
|
if let Err(guar) = has_error {
|
||||||
let err_inputs = self.err_args(args_no_rcvr.len(), guar);
|
let err_inputs = self.err_args(
|
||||||
|
method.map_or(args_no_rcvr.len(), |method| method.sig.inputs().len() - 1),
|
||||||
|
guar,
|
||||||
|
);
|
||||||
let err_output = Ty::new_error(self.tcx, guar);
|
let err_output = Ty::new_error(self.tcx, guar);
|
||||||
|
|
||||||
let err_inputs = match tuple_arguments {
|
let err_inputs = match tuple_arguments {
|
||||||
|
@ -2374,11 +2377,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let check_for_matched_generics = || {
|
let check_for_matched_generics = || {
|
||||||
if matched_inputs.iter().any(|x| x.is_some())
|
if matched_inputs.iter().any(|x| x.is_some())
|
||||||
&& params_with_generics.iter().any(|x| x.1.is_some())
|
&& params_with_generics.iter().any(|(x, _)| x.is_some())
|
||||||
{
|
{
|
||||||
for &(idx, generic, _) in ¶ms_with_generics {
|
for (idx, (generic, _)) in params_with_generics.iter_enumerated() {
|
||||||
// Param has to have a generic and be matched to be relevant
|
// Param has to have a generic and be matched to be relevant
|
||||||
if matched_inputs[idx.into()].is_none() {
|
if matched_inputs[idx].is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2386,10 +2389,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
for unmatching_idx in idx + 1..params_with_generics.len() {
|
for unmatching_idx in
|
||||||
if matched_inputs[unmatching_idx.into()].is_none()
|
idx.plus(1)..ExpectedIdx::from_usize(params_with_generics.len())
|
||||||
|
{
|
||||||
|
if matched_inputs[unmatching_idx].is_none()
|
||||||
&& let Some(unmatched_idx_param_generic) =
|
&& let Some(unmatched_idx_param_generic) =
|
||||||
params_with_generics[unmatching_idx].1
|
params_with_generics[unmatching_idx].0
|
||||||
&& unmatched_idx_param_generic.name.ident()
|
&& unmatched_idx_param_generic.name.ident()
|
||||||
== generic.name.ident()
|
== generic.name.ident()
|
||||||
{
|
{
|
||||||
|
@ -2404,61 +2409,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let check_for_matched_generics = check_for_matched_generics();
|
let check_for_matched_generics = check_for_matched_generics();
|
||||||
|
|
||||||
for &(idx, generic_param, param) in
|
for (idx, &(generic_param, param)) in
|
||||||
params_with_generics.iter().filter(|&(idx, _, _)| {
|
params_with_generics.iter_enumerated().filter(|&(idx, _)| {
|
||||||
check_for_matched_generics
|
check_for_matched_generics
|
||||||
|| expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
|
|| expected_idx
|
||||||
|
.is_none_or(|expected_idx| expected_idx == idx.as_usize())
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let Some(generic_param) = generic_param else {
|
let Some(generic_param) = generic_param else {
|
||||||
spans.push_span_label(param.span, "");
|
spans.push_span_label(param.span(), "");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
|
let other_params_matched: Vec<(ExpectedIdx, FnParam<'_>)> =
|
||||||
.iter()
|
params_with_generics
|
||||||
.filter(|(other_idx, other_generic_param, _)| {
|
.iter_enumerated()
|
||||||
if *other_idx == idx {
|
.filter(|&(other_idx, &(other_generic_param, _))| {
|
||||||
return false;
|
if other_idx == idx {
|
||||||
}
|
return false;
|
||||||
let Some(other_generic_param) = other_generic_param else {
|
}
|
||||||
return false;
|
let Some(other_generic_param) = other_generic_param else {
|
||||||
};
|
return false;
|
||||||
if matched_inputs[idx.into()].is_none()
|
};
|
||||||
&& matched_inputs[(*other_idx).into()].is_none()
|
if matched_inputs[idx].is_none()
|
||||||
{
|
&& matched_inputs[other_idx].is_none()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
if matched_inputs[idx.into()].is_some()
|
}
|
||||||
&& matched_inputs[(*other_idx).into()].is_some()
|
if matched_inputs[idx].is_some()
|
||||||
{
|
&& matched_inputs[other_idx].is_some()
|
||||||
return false;
|
{
|
||||||
}
|
return false;
|
||||||
other_generic_param.name.ident() == generic_param.name.ident()
|
}
|
||||||
})
|
other_generic_param.name.ident() == generic_param.name.ident()
|
||||||
.map(|&(other_idx, _, other_param)| (other_idx, other_param))
|
})
|
||||||
.collect();
|
.map(|(other_idx, &(_, other_param))| (other_idx, other_param))
|
||||||
|
.collect();
|
||||||
|
|
||||||
if !other_params_matched.is_empty() {
|
if !other_params_matched.is_empty() {
|
||||||
let other_param_matched_names: Vec<String> = other_params_matched
|
let other_param_matched_names: Vec<String> = other_params_matched
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(idx, other_param)| {
|
.map(|(idx, other_param)| {
|
||||||
if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind
|
if let Some(name) = other_param.name() {
|
||||||
{
|
format!("`{name}`")
|
||||||
format!("`{ident}`")
|
|
||||||
} else {
|
} else {
|
||||||
format!("parameter #{}", idx + 1)
|
format!("parameter #{}", idx.as_u32() + 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let matched_ty = self
|
let matched_ty = self
|
||||||
.resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
|
.resolve_vars_if_possible(formal_and_expected_inputs[idx].1)
|
||||||
.sort_string(self.tcx);
|
.sort_string(self.tcx);
|
||||||
|
|
||||||
if matched_inputs[idx.into()].is_some() {
|
if matched_inputs[idx].is_some() {
|
||||||
spans.push_span_label(
|
spans.push_span_label(
|
||||||
param.span,
|
param.span(),
|
||||||
format!(
|
format!(
|
||||||
"{} need{} to match the {} type of this parameter",
|
"{} need{} to match the {} type of this parameter",
|
||||||
listify(&other_param_matched_names, |n| n.to_string())
|
listify(&other_param_matched_names, |n| n.to_string())
|
||||||
|
@ -2473,7 +2479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
spans.push_span_label(
|
spans.push_span_label(
|
||||||
param.span,
|
param.span(),
|
||||||
format!(
|
format!(
|
||||||
"this parameter needs to match the {} type of {}",
|
"this parameter needs to match the {} type of {}",
|
||||||
matched_ty,
|
matched_ty,
|
||||||
|
@ -2484,7 +2490,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
generics_with_unmatched_params.push(generic_param);
|
generics_with_unmatched_params.push(generic_param);
|
||||||
} else {
|
} else {
|
||||||
spans.push_span_label(param.span, "");
|
spans.push_span_label(param.span(), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2502,19 +2508,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let param_idents_matching: Vec<String> = params_with_generics
|
let param_idents_matching: Vec<String> = params_with_generics
|
||||||
.iter()
|
.iter_enumerated()
|
||||||
.filter(|(_, generic, _)| {
|
.filter(|&(_, &(generic, _))| {
|
||||||
if let Some(generic) = generic {
|
if let Some(generic) = generic {
|
||||||
generic.name.ident() == generic_param.name.ident()
|
generic.name.ident() == generic_param.name.ident()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|(idx, _, param)| {
|
.map(|(idx, &(_, param))| {
|
||||||
if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
|
if let Some(name) = param.name() {
|
||||||
format!("`{ident}`")
|
format!("`{name}`")
|
||||||
} else {
|
} else {
|
||||||
format!("parameter #{}", idx + 1)
|
format!("parameter #{}", idx.as_u32() + 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -2607,12 +2613,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) {
|
if let Some(params_with_generics) = self.get_hir_params_with_generics(def_id, is_method) {
|
||||||
debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
|
debug_assert_eq!(params_with_generics.len(), matched_inputs.len());
|
||||||
for &(idx, generic_param, _) in ¶ms_with_generics {
|
for (idx, (generic_param, _)) in params_with_generics.iter_enumerated() {
|
||||||
if matched_inputs[idx.into()].is_none() {
|
if matched_inputs[idx].is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
|
let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.to_provided_idx())
|
||||||
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2620,32 +2627,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut idxs_matched: Vec<usize> = vec![];
|
let idxs_matched = params_with_generics
|
||||||
for &(other_idx, _, _) in
|
.iter_enumerated()
|
||||||
params_with_generics.iter().filter(|&&(other_idx, other_generic_param, _)| {
|
.filter(|&(other_idx, (other_generic_param, _))| {
|
||||||
if other_idx == idx {
|
if other_idx == idx {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let Some(other_generic_param) = other_generic_param else {
|
let Some(other_generic_param) = other_generic_param else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if matched_inputs[other_idx.into()].is_some() {
|
if matched_inputs[other_idx].is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
other_generic_param.name.ident() == generic_param.name.ident()
|
other_generic_param.name.ident() == generic_param.name.ident()
|
||||||
})
|
})
|
||||||
{
|
.count();
|
||||||
idxs_matched.push(other_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if idxs_matched.is_empty() {
|
if idxs_matched == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let expected_display_type = self
|
let expected_display_type = self
|
||||||
.resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
|
.resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
|
||||||
.sort_string(self.tcx);
|
.sort_string(self.tcx);
|
||||||
let label = if idxs_matched.len() == params_with_generics.len() - 1 {
|
let label = if idxs_matched == params_with_generics.len() - 1 {
|
||||||
format!(
|
format!(
|
||||||
"expected all arguments to be this {} type because they need to match the type of this parameter",
|
"expected all arguments to be this {} type because they need to match the type of this parameter",
|
||||||
expected_display_type
|
expected_display_type
|
||||||
|
@ -2664,62 +2669,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the parameters of a function, with their generic parameters if those are the full
|
/// Returns the parameters of a function, with their generic parameters if those are the full
|
||||||
/// type of that parameter. Returns `None` if the function body is unavailable (eg is an instrinsic).
|
/// type of that parameter. Returns `None` if the function has no generics or the body is
|
||||||
|
/// unavailable (eg is an instrinsic).
|
||||||
fn get_hir_params_with_generics(
|
fn get_hir_params_with_generics(
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
is_method: bool,
|
is_method: bool,
|
||||||
) -> Option<Vec<(usize, Option<&hir::GenericParam<'_>>, &hir::Param<'_>)>> {
|
) -> Option<IndexVec<ExpectedIdx, (Option<&hir::GenericParam<'_>>, FnParam<'_>)>> {
|
||||||
let fn_node = self.tcx.hir().get_if_local(def_id)?;
|
let (sig, generics, body_id, param_names) = match self.tcx.hir().get_if_local(def_id)? {
|
||||||
let fn_decl = fn_node.fn_decl()?;
|
hir::Node::TraitItem(&hir::TraitItem {
|
||||||
|
generics,
|
||||||
let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_decl
|
kind: hir::TraitItemKind::Fn(sig, trait_fn),
|
||||||
.inputs
|
..
|
||||||
.into_iter()
|
}) => match trait_fn {
|
||||||
.skip(if is_method { 1 } else { 0 })
|
hir::TraitFn::Required(params) => (sig, generics, None, Some(params)),
|
||||||
.map(|param| {
|
hir::TraitFn::Provided(body) => (sig, generics, Some(body), None),
|
||||||
if let hir::TyKind::Path(QPath::Resolved(
|
},
|
||||||
_,
|
hir::Node::ImplItem(&hir::ImplItem {
|
||||||
hir::Path { res: Res::Def(_, res_def_id), .. },
|
generics,
|
||||||
)) = param.kind
|
kind: hir::ImplItemKind::Fn(sig, body),
|
||||||
{
|
..
|
||||||
fn_node
|
|
||||||
.generics()
|
|
||||||
.into_iter()
|
|
||||||
.flat_map(|generics| generics.params)
|
|
||||||
.find(|param| ¶m.def_id.to_def_id() == res_def_id)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
| hir::Node::Item(&hir::Item {
|
||||||
|
kind: hir::ItemKind::Fn { sig, generics, body, .. },
|
||||||
|
..
|
||||||
|
}) => (sig, generics, Some(body), None),
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut params: Vec<&hir::Param<'_>> = self
|
// Make sure to remove both the receiver and variadic argument. Both are removed
|
||||||
.tcx
|
// when matching parameter types.
|
||||||
.hir()
|
let fn_inputs = sig.decl.inputs.get(is_method as usize..)?.iter().map(|param| {
|
||||||
.body(fn_node.body_id()?)
|
if let hir::TyKind::Path(QPath::Resolved(
|
||||||
.params
|
_,
|
||||||
.into_iter()
|
&hir::Path { res: Res::Def(_, res_def_id), .. },
|
||||||
.skip(if is_method { 1 } else { 0 })
|
)) = param.kind
|
||||||
.collect();
|
{
|
||||||
|
generics.params.iter().find(|param| param.def_id.to_def_id() == res_def_id)
|
||||||
// The surrounding code expects variadic functions to not have a parameter representing
|
} else {
|
||||||
// the "..." parameter. This is already true of the FnDecl but not of the body params, so
|
None
|
||||||
// we drop it if it exists.
|
}
|
||||||
|
});
|
||||||
if fn_decl.c_variadic {
|
match (body_id, param_names) {
|
||||||
params.pop();
|
(Some(_), Some(_)) | (None, None) => unreachable!(),
|
||||||
|
(Some(body), None) => {
|
||||||
|
let params = self.tcx.hir().body(body).params;
|
||||||
|
let params =
|
||||||
|
params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
|
||||||
|
debug_assert_eq!(params.len(), fn_inputs.len());
|
||||||
|
Some(fn_inputs.zip(params.iter().map(|param| FnParam::Param(param))).collect())
|
||||||
|
}
|
||||||
|
(None, Some(params)) => {
|
||||||
|
let params = params.get(is_method as usize..)?;
|
||||||
|
debug_assert_eq!(params.len(), fn_inputs.len());
|
||||||
|
Some(fn_inputs.zip(params.iter().map(|param| FnParam::Name(param))).collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert_eq!(params.len(), generic_params.len());
|
|
||||||
Some(
|
|
||||||
generic_params
|
|
||||||
.into_iter()
|
|
||||||
.zip(params)
|
|
||||||
.enumerate()
|
|
||||||
.map(|(a, (b, c))| (a, b, c))
|
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2742,3 +2747,27 @@ impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
|
||||||
hir::intravisit::walk_expr(self, ex);
|
hir::intravisit::walk_expr(self, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum FnParam<'hir> {
|
||||||
|
Param(&'hir hir::Param<'hir>),
|
||||||
|
Name(&'hir Ident),
|
||||||
|
}
|
||||||
|
impl FnParam<'_> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
match self {
|
||||||
|
Self::Param(x) => x.span,
|
||||||
|
Self::Name(x) => x.span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> Option<Symbol> {
|
||||||
|
match self {
|
||||||
|
Self::Param(x) if let hir::PatKind::Binding(_, _, ident, _) = x.pat.kind => {
|
||||||
|
Some(ident.name)
|
||||||
|
}
|
||||||
|
Self::Name(x) if x.name != kw::Empty => Some(x.name),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -186,8 +186,6 @@ fn typeck_with_inspect<'tcx>(
|
||||||
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
|
let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id)));
|
||||||
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
|
fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code);
|
||||||
|
|
||||||
fcx.require_type_is_sized(expected_type, body.value.span, ObligationCauseCode::ConstSized);
|
|
||||||
|
|
||||||
// Gather locals in statics (because of block expressions).
|
// Gather locals in statics (because of block expressions).
|
||||||
GatherLocalsVisitor::new(&fcx).visit_body(body);
|
GatherLocalsVisitor::new(&fcx).visit_body(body);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//! overview of how lints are implemented.
|
//! overview of how lints are implemented.
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{iter, slice};
|
use std::slice;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_data_structures::sync;
|
use rustc_data_structures::sync;
|
||||||
|
@ -718,30 +718,6 @@ impl<'tcx> LateContext<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a `DefId`'s path matches the given absolute type path usage.
|
|
||||||
///
|
|
||||||
/// Anonymous scopes such as `extern` imports are matched with `kw::Empty`;
|
|
||||||
/// inherent `impl` blocks are matched with the name of the type.
|
|
||||||
///
|
|
||||||
/// Instead of using this method, it is often preferable to instead use
|
|
||||||
/// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors
|
|
||||||
/// as paths get invalidated if the target definition moves.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```rust,ignore (no context or def id available)
|
|
||||||
/// if cx.match_def_path(def_id, &[sym::core, sym::option, sym::Option]) {
|
|
||||||
/// // The given `def_id` is that of an `Option` type
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Used by clippy, but should be replaced by diagnostic items eventually.
|
|
||||||
pub fn match_def_path(&self, def_id: DefId, path: &[Symbol]) -> bool {
|
|
||||||
let names = self.get_def_path(def_id);
|
|
||||||
|
|
||||||
names.len() == path.len() && iter::zip(names, path).all(|(a, &b)| a == b)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the absolute path of `def_id` as a vector of `Symbol`.
|
/// Gets the absolute path of `def_id` as a vector of `Symbol`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|
|
@ -937,6 +937,7 @@ impl<'hir> Map<'hir> {
|
||||||
Node::TraitRef(tr) => tr.path.span,
|
Node::TraitRef(tr) => tr.path.span,
|
||||||
Node::OpaqueTy(op) => op.span,
|
Node::OpaqueTy(op) => op.span,
|
||||||
Node::Pat(pat) => pat.span,
|
Node::Pat(pat) => pat.span,
|
||||||
|
Node::TyPat(pat) => pat.span,
|
||||||
Node::PatField(field) => field.span,
|
Node::PatField(field) => field.span,
|
||||||
Node::PatExpr(lit) => lit.span,
|
Node::PatExpr(lit) => lit.span,
|
||||||
Node::Arm(arm) => arm.span,
|
Node::Arm(arm) => arm.span,
|
||||||
|
@ -1212,6 +1213,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||||
Node::TraitRef(_) => node_str("trait ref"),
|
Node::TraitRef(_) => node_str("trait ref"),
|
||||||
Node::OpaqueTy(_) => node_str("opaque type"),
|
Node::OpaqueTy(_) => node_str("opaque type"),
|
||||||
Node::Pat(_) => node_str("pat"),
|
Node::Pat(_) => node_str("pat"),
|
||||||
|
Node::TyPat(_) => node_str("pat ty"),
|
||||||
Node::PatField(_) => node_str("pattern field"),
|
Node::PatField(_) => node_str("pattern field"),
|
||||||
Node::PatExpr(_) => node_str("pattern literal"),
|
Node::PatExpr(_) => node_str("pattern literal"),
|
||||||
Node::Param(_) => node_str("param"),
|
Node::Param(_) => node_str("param"),
|
||||||
|
|
|
@ -6,9 +6,9 @@ use rustc_middle::ty;
|
||||||
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
use rustc_middle::ty::CanonicalUserTypeAnnotation;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::thir::cx::Cx;
|
use crate::thir::cx::ThirBuildCx;
|
||||||
|
|
||||||
impl<'tcx> Cx<'tcx> {
|
impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> BlockId {
|
pub(crate) fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> BlockId {
|
||||||
// We have to eagerly lower the "spine" of the statements
|
// We have to eagerly lower the "spine" of the statements
|
||||||
// in order to get the lexical scoping correctly.
|
// in order to get the lexical scoping correctly.
|
||||||
|
|
|
@ -21,10 +21,9 @@ use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::{Span, sym};
|
use rustc_span::{Span, sym};
|
||||||
use tracing::{debug, info, instrument, trace};
|
use tracing::{debug, info, instrument, trace};
|
||||||
|
|
||||||
use crate::thir::cx::Cx;
|
use crate::thir::cx::ThirBuildCx;
|
||||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
|
||||||
|
|
||||||
impl<'tcx> Cx<'tcx> {
|
impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
/// Create a THIR expression for the given HIR expression. This expands all
|
/// Create a THIR expression for the given HIR expression. This expands all
|
||||||
/// adjustments and directly adds the type information from the
|
/// adjustments and directly adds the type information from the
|
||||||
/// `typeck_results`. See the [dev-guide] for more details.
|
/// `typeck_results`. See the [dev-guide] for more details.
|
||||||
|
@ -142,9 +141,9 @@ impl<'tcx> Cx<'tcx> {
|
||||||
Adjust::Deref(Some(deref)) => {
|
Adjust::Deref(Some(deref)) => {
|
||||||
// We don't need to do call adjust_span here since
|
// We don't need to do call adjust_span here since
|
||||||
// deref coercions always start with a built-in deref.
|
// deref coercions always start with a built-in deref.
|
||||||
let call_def_id = deref.method_call(self.tcx());
|
let call_def_id = deref.method_call(self.tcx);
|
||||||
let overloaded_callee =
|
let overloaded_callee =
|
||||||
Ty::new_fn_def(self.tcx(), call_def_id, self.tcx().mk_args(&[expr.ty.into()]));
|
Ty::new_fn_def(self.tcx, call_def_id, self.tcx.mk_args(&[expr.ty.into()]));
|
||||||
|
|
||||||
expr = Expr {
|
expr = Expr {
|
||||||
temp_lifetime,
|
temp_lifetime,
|
||||||
|
@ -253,10 +252,10 @@ impl<'tcx> Cx<'tcx> {
|
||||||
|
|
||||||
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
||||||
// using a coercion (or is a no-op).
|
// using a coercion (or is a no-op).
|
||||||
if self.typeck_results().is_coercion_cast(source.hir_id) {
|
if self.typeck_results.is_coercion_cast(source.hir_id) {
|
||||||
// Convert the lexpr to a vexpr.
|
// Convert the lexpr to a vexpr.
|
||||||
ExprKind::Use { source: self.mirror_expr(source) }
|
ExprKind::Use { source: self.mirror_expr(source) }
|
||||||
} else if self.typeck_results().expr_ty(source).is_ref() {
|
} else if self.typeck_results.expr_ty(source).is_ref() {
|
||||||
// Special cased so that we can type check that the element
|
// Special cased so that we can type check that the element
|
||||||
// type of the source matches the pointed to type of the
|
// type of the source matches the pointed to type of the
|
||||||
// destination.
|
// destination.
|
||||||
|
@ -266,8 +265,8 @@ impl<'tcx> Cx<'tcx> {
|
||||||
is_from_as_cast: true,
|
is_from_as_cast: true,
|
||||||
}
|
}
|
||||||
} else if let hir::ExprKind::Path(ref qpath) = source.kind
|
} else if let hir::ExprKind::Path(ref qpath) = source.kind
|
||||||
&& let res = self.typeck_results().qpath_res(qpath, source.hir_id)
|
&& let res = self.typeck_results.qpath_res(qpath, source.hir_id)
|
||||||
&& let ty = self.typeck_results().node_type(source.hir_id)
|
&& let ty = self.typeck_results.node_type(source.hir_id)
|
||||||
&& let ty::Adt(adt_def, args) = ty.kind()
|
&& let ty::Adt(adt_def, args) = ty.kind()
|
||||||
&& let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
|
&& let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
|
||||||
{
|
{
|
||||||
|
@ -330,7 +329,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
#[instrument(level = "debug", skip(self), ret)]
|
#[instrument(level = "debug", skip(self), ret)]
|
||||||
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
|
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let expr_ty = self.typeck_results().expr_ty(expr);
|
let expr_ty = self.typeck_results.expr_ty(expr);
|
||||||
let (temp_lifetime, backwards_incompatible) =
|
let (temp_lifetime, backwards_incompatible) =
|
||||||
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
|
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
|
||||||
|
|
||||||
|
@ -354,7 +353,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Call(fun, ref args) => {
|
hir::ExprKind::Call(fun, ref args) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
// The callee is something implementing Fn, FnMut, or FnOnce.
|
// The callee is something implementing Fn, FnMut, or FnOnce.
|
||||||
// Find the actual method implementation being called and
|
// Find the actual method implementation being called and
|
||||||
// build the appropriate UFCS call expression with the
|
// build the appropriate UFCS call expression with the
|
||||||
|
@ -364,7 +363,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
|
|
||||||
let method = self.method_callee(expr, fun.span, None);
|
let method = self.method_callee(expr, fun.span, None);
|
||||||
|
|
||||||
let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e));
|
let arg_tys = args.iter().map(|e| self.typeck_results.expr_ty_adjusted(e));
|
||||||
let tupled_args = Expr {
|
let tupled_args = Expr {
|
||||||
ty: Ty::new_tup_from_iter(tcx, arg_tys),
|
ty: Ty::new_tup_from_iter(tcx, arg_tys),
|
||||||
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
|
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
|
||||||
|
@ -380,7 +379,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
from_hir_call: true,
|
from_hir_call: true,
|
||||||
fn_span: expr.span,
|
fn_span: expr.span,
|
||||||
}
|
}
|
||||||
} else if let ty::FnDef(def_id, _) = self.typeck_results().expr_ty(fun).kind()
|
} else if let ty::FnDef(def_id, _) = self.typeck_results.expr_ty(fun).kind()
|
||||||
&& let Some(intrinsic) = self.tcx.intrinsic(def_id)
|
&& let Some(intrinsic) = self.tcx.intrinsic(def_id)
|
||||||
&& intrinsic.name == sym::box_new
|
&& intrinsic.name == sym::box_new
|
||||||
{
|
{
|
||||||
|
@ -413,7 +412,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
},
|
},
|
||||||
hir::QPath::TypeRelative(_ty, _) => {
|
hir::QPath::TypeRelative(_ty, _) => {
|
||||||
if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
|
if let Some((DefKind::Ctor(_, CtorKind::Fn), ctor_id)) =
|
||||||
self.typeck_results().type_dependent_def(fun.hir_id)
|
self.typeck_results.type_dependent_def(fun.hir_id)
|
||||||
{
|
{
|
||||||
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
|
Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -426,8 +425,8 @@ impl<'tcx> Cx<'tcx> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
if let Some((adt_def, index)) = adt_data {
|
if let Some((adt_def, index)) = adt_data {
|
||||||
let node_args = self.typeck_results().node_args(fun.hir_id);
|
let node_args = self.typeck_results.node_args(fun.hir_id);
|
||||||
let user_provided_types = self.typeck_results().user_provided_types();
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
let user_ty =
|
let user_ty =
|
||||||
user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
|
user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
|
||||||
if let ty::UserTypeKind::TypeOf(ref mut did, _) =
|
if let ty::UserTypeKind::TypeOf(ref mut did, _) =
|
||||||
|
@ -457,7 +456,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
ExprKind::Call {
|
ExprKind::Call {
|
||||||
ty: self.typeck_results().node_type(fun.hir_id),
|
ty: self.typeck_results.node_type(fun.hir_id),
|
||||||
fun: self.mirror_expr(fun),
|
fun: self.mirror_expr(fun),
|
||||||
args: self.mirror_exprs(args),
|
args: self.mirror_exprs(args),
|
||||||
from_hir_call: true,
|
from_hir_call: true,
|
||||||
|
@ -482,7 +481,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::AssignOp(op, lhs, rhs) => {
|
hir::ExprKind::AssignOp(op, lhs, rhs) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let lhs = self.mirror_expr(lhs);
|
let lhs = self.mirror_expr(lhs);
|
||||||
let rhs = self.mirror_expr(rhs);
|
let rhs = self.mirror_expr(rhs);
|
||||||
self.overloaded_operator(expr, Box::new([lhs, rhs]))
|
self.overloaded_operator(expr, Box::new([lhs, rhs]))
|
||||||
|
@ -498,7 +497,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
|
hir::ExprKind::Lit(lit) => ExprKind::Literal { lit, neg: false },
|
||||||
|
|
||||||
hir::ExprKind::Binary(op, lhs, rhs) => {
|
hir::ExprKind::Binary(op, lhs, rhs) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let lhs = self.mirror_expr(lhs);
|
let lhs = self.mirror_expr(lhs);
|
||||||
let rhs = self.mirror_expr(rhs);
|
let rhs = self.mirror_expr(rhs);
|
||||||
self.overloaded_operator(expr, Box::new([lhs, rhs]))
|
self.overloaded_operator(expr, Box::new([lhs, rhs]))
|
||||||
|
@ -527,7 +526,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Index(lhs, index, brackets_span) => {
|
hir::ExprKind::Index(lhs, index, brackets_span) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let lhs = self.mirror_expr(lhs);
|
let lhs = self.mirror_expr(lhs);
|
||||||
let index = self.mirror_expr(index);
|
let index = self.mirror_expr(index);
|
||||||
self.overloaded_place(
|
self.overloaded_place(
|
||||||
|
@ -543,7 +542,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
|
hir::ExprKind::Unary(hir::UnOp::Deref, arg) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let arg = self.mirror_expr(arg);
|
let arg = self.mirror_expr(arg);
|
||||||
self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
|
self.overloaded_place(expr, expr_ty, None, Box::new([arg]), expr.span)
|
||||||
} else {
|
} else {
|
||||||
|
@ -552,7 +551,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
|
hir::ExprKind::Unary(hir::UnOp::Not, arg) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let arg = self.mirror_expr(arg);
|
let arg = self.mirror_expr(arg);
|
||||||
self.overloaded_operator(expr, Box::new([arg]))
|
self.overloaded_operator(expr, Box::new([arg]))
|
||||||
} else {
|
} else {
|
||||||
|
@ -561,7 +560,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
|
hir::ExprKind::Unary(hir::UnOp::Neg, arg) => {
|
||||||
if self.typeck_results().is_method_call(expr) {
|
if self.typeck_results.is_method_call(expr) {
|
||||||
let arg = self.mirror_expr(arg);
|
let arg = self.mirror_expr(arg);
|
||||||
self.overloaded_operator(expr, Box::new([arg]))
|
self.overloaded_operator(expr, Box::new([arg]))
|
||||||
} else if let hir::ExprKind::Lit(lit) = arg.kind {
|
} else if let hir::ExprKind::Lit(lit) = arg.kind {
|
||||||
|
@ -574,7 +573,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
|
hir::ExprKind::Struct(qpath, fields, ref base) => match expr_ty.kind() {
|
||||||
ty::Adt(adt, args) => match adt.adt_kind() {
|
ty::Adt(adt, args) => match adt.adt_kind() {
|
||||||
AdtKind::Struct | AdtKind::Union => {
|
AdtKind::Struct | AdtKind::Union => {
|
||||||
let user_provided_types = self.typeck_results().user_provided_types();
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||||
debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
|
debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty);
|
||||||
ExprKind::Adt(Box::new(AdtExpr {
|
ExprKind::Adt(Box::new(AdtExpr {
|
||||||
|
@ -586,15 +585,14 @@ impl<'tcx> Cx<'tcx> {
|
||||||
base: match base {
|
base: match base {
|
||||||
hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
|
hir::StructTailExpr::Base(base) => AdtExprBase::Base(FruInfo {
|
||||||
base: self.mirror_expr(base),
|
base: self.mirror_expr(base),
|
||||||
field_types: self.typeck_results().fru_field_types()
|
field_types: self.typeck_results.fru_field_types()[expr.hir_id]
|
||||||
[expr.hir_id]
|
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.collect(),
|
.collect(),
|
||||||
}),
|
}),
|
||||||
hir::StructTailExpr::DefaultFields(_) => {
|
hir::StructTailExpr::DefaultFields(_) => {
|
||||||
AdtExprBase::DefaultFields(
|
AdtExprBase::DefaultFields(
|
||||||
self.typeck_results().fru_field_types()[expr.hir_id]
|
self.typeck_results.fru_field_types()[expr.hir_id]
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -605,7 +603,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
AdtKind::Enum => {
|
AdtKind::Enum => {
|
||||||
let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
|
let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
|
||||||
match res {
|
match res {
|
||||||
Res::Def(DefKind::Variant, variant_id) => {
|
Res::Def(DefKind::Variant, variant_id) => {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
@ -615,8 +613,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
));
|
));
|
||||||
|
|
||||||
let index = adt.variant_index_with_id(variant_id);
|
let index = adt.variant_index_with_id(variant_id);
|
||||||
let user_provided_types =
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
self.typeck_results().user_provided_types();
|
|
||||||
let user_ty =
|
let user_ty =
|
||||||
user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||||
debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
|
debug!("make_mirror_unadjusted: (variant) user_ty={:?}", user_ty);
|
||||||
|
@ -629,8 +626,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
base: match base {
|
base: match base {
|
||||||
hir::StructTailExpr::DefaultFields(_) => {
|
hir::StructTailExpr::DefaultFields(_) => {
|
||||||
AdtExprBase::DefaultFields(
|
AdtExprBase::DefaultFields(
|
||||||
self.typeck_results().fru_field_types()
|
self.typeck_results.fru_field_types()[expr.hir_id]
|
||||||
[expr.hir_id]
|
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -655,7 +651,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
},
|
},
|
||||||
|
|
||||||
hir::ExprKind::Closure { .. } => {
|
hir::ExprKind::Closure { .. } => {
|
||||||
let closure_ty = self.typeck_results().expr_ty(expr);
|
let closure_ty = self.typeck_results.expr_ty(expr);
|
||||||
let (def_id, args, movability) = match *closure_ty.kind() {
|
let (def_id, args, movability) = match *closure_ty.kind() {
|
||||||
ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
|
ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
|
||||||
ty::Coroutine(def_id, args) => {
|
ty::Coroutine(def_id, args) => {
|
||||||
|
@ -703,7 +699,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::Path(ref qpath) => {
|
hir::ExprKind::Path(ref qpath) => {
|
||||||
let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
|
let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
|
||||||
self.convert_path_expr(expr, res)
|
self.convert_path_expr(expr, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +768,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprKind::ConstBlock(ref anon_const) => {
|
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||||
let ty = self.typeck_results().node_type(anon_const.hir_id);
|
let ty = self.typeck_results.node_type(anon_const.hir_id);
|
||||||
let did = anon_const.def_id.to_def_id();
|
let did = anon_const.def_id.to_def_id();
|
||||||
let typeck_root_def_id = tcx.typeck_root_def_id(did);
|
let typeck_root_def_id = tcx.typeck_root_def_id(did);
|
||||||
let parent_args =
|
let parent_args =
|
||||||
|
@ -783,7 +779,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
// Now comes the rote stuff:
|
// Now comes the rote stuff:
|
||||||
hir::ExprKind::Repeat(v, _) => {
|
hir::ExprKind::Repeat(v, _) => {
|
||||||
let ty = self.typeck_results().expr_ty(expr);
|
let ty = self.typeck_results.expr_ty(expr);
|
||||||
let ty::Array(_, count) = ty.kind() else {
|
let ty::Array(_, count) = ty.kind() else {
|
||||||
span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
|
span_bug!(expr.span, "unexpected repeat expr ty: {:?}", ty);
|
||||||
};
|
};
|
||||||
|
@ -837,7 +833,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
match_source,
|
match_source,
|
||||||
},
|
},
|
||||||
hir::ExprKind::Loop(body, ..) => {
|
hir::ExprKind::Loop(body, ..) => {
|
||||||
let block_ty = self.typeck_results().node_type(body.hir_id);
|
let block_ty = self.typeck_results.node_type(body.hir_id);
|
||||||
let (temp_lifetime, backwards_incompatible) = self
|
let (temp_lifetime, backwards_incompatible) = self
|
||||||
.rvalue_scopes
|
.rvalue_scopes
|
||||||
.temporary_scope(self.region_scope_tree, body.hir_id.local_id);
|
.temporary_scope(self.region_scope_tree, body.hir_id.local_id);
|
||||||
|
@ -957,7 +953,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
|
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
|
||||||
| Res::Def(DefKind::Const, _)
|
| Res::Def(DefKind::Const, _)
|
||||||
| Res::Def(DefKind::AssocConst, _) => {
|
| Res::Def(DefKind::AssocConst, _) => {
|
||||||
self.typeck_results().user_provided_types().get(hir_id).copied().map(Box::new)
|
self.typeck_results.user_provided_types().get(hir_id).copied().map(Box::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A unit struct/variant which is used as a value (e.g.,
|
// A unit struct/variant which is used as a value (e.g.,
|
||||||
|
@ -989,17 +985,13 @@ impl<'tcx> Cx<'tcx> {
|
||||||
Some(fn_def) => (fn_def, None),
|
Some(fn_def) => (fn_def, None),
|
||||||
None => {
|
None => {
|
||||||
let (kind, def_id) =
|
let (kind, def_id) =
|
||||||
self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| {
|
self.typeck_results.type_dependent_def(expr.hir_id).unwrap_or_else(|| {
|
||||||
span_bug!(expr.span, "no type-dependent def for method callee")
|
span_bug!(expr.span, "no type-dependent def for method callee")
|
||||||
});
|
});
|
||||||
let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
|
let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
|
||||||
debug!("method_callee: user_ty={:?}", user_ty);
|
debug!("method_callee: user_ty={:?}", user_ty);
|
||||||
(
|
(
|
||||||
Ty::new_fn_def(
|
Ty::new_fn_def(self.tcx, def_id, self.typeck_results.node_args(expr.hir_id)),
|
||||||
self.tcx(),
|
|
||||||
def_id,
|
|
||||||
self.typeck_results().node_args(expr.hir_id),
|
|
||||||
),
|
|
||||||
user_ty,
|
user_ty,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1017,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
|
fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
|
||||||
let args = self.typeck_results().node_args(expr.hir_id);
|
let args = self.typeck_results.node_args(expr.hir_id);
|
||||||
match res {
|
match res {
|
||||||
// A regular function, constructor function or a constant.
|
// A regular function, constructor function or a constant.
|
||||||
Res::Def(DefKind::Fn, _)
|
Res::Def(DefKind::Fn, _)
|
||||||
|
@ -1060,7 +1052,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
let user_provided_types = self.typeck_results.user_provided_types();
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
|
||||||
debug!("convert_path_expr: user_ty={:?}", user_ty);
|
debug!("convert_path_expr: user_ty={:?}", user_ty);
|
||||||
let ty = self.typeck_results().node_type(expr.hir_id);
|
let ty = self.typeck_results.node_type(expr.hir_id);
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
// A unit struct/variant which is used as a value.
|
// A unit struct/variant which is used as a value.
|
||||||
// We return a completely different ExprKind here to account for this special case.
|
// We return a completely different ExprKind here to account for this special case.
|
||||||
|
|
|
@ -16,15 +16,15 @@ use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::thir::pattern::pat_from_hir;
|
use crate::thir::pattern::pat_from_hir;
|
||||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
|
||||||
|
|
||||||
|
/// Query implementation for [`TyCtxt::thir_body`].
|
||||||
pub(crate) fn thir_body(
|
pub(crate) fn thir_body(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
owner_def: LocalDefId,
|
owner_def: LocalDefId,
|
||||||
) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
|
) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> {
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
let body = hir.body_owned_by(owner_def);
|
let body = hir.body_owned_by(owner_def);
|
||||||
let mut cx = Cx::new(tcx, owner_def);
|
let mut cx = ThirBuildCx::new(tcx, owner_def);
|
||||||
if let Some(reported) = cx.typeck_results.tainted_by_errors {
|
if let Some(reported) = cx.typeck_results.tainted_by_errors {
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,10 @@ pub(crate) fn thir_body(
|
||||||
Ok((tcx.alloc_steal_thir(cx.thir), expr))
|
Ok((tcx.alloc_steal_thir(cx.thir), expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Cx<'tcx> {
|
/// Context for lowering HIR to THIR for a single function body (or other kind of body).
|
||||||
|
struct ThirBuildCx<'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
/// The THIR data that this context is building.
|
||||||
thir: Thir<'tcx>,
|
thir: Thir<'tcx>,
|
||||||
|
|
||||||
typing_env: ty::TypingEnv<'tcx>,
|
typing_env: ty::TypingEnv<'tcx>,
|
||||||
|
@ -69,8 +71,8 @@ struct Cx<'tcx> {
|
||||||
body_owner: DefId,
|
body_owner: DefId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Cx<'tcx> {
|
impl<'tcx> ThirBuildCx<'tcx> {
|
||||||
fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> {
|
fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
|
||||||
let typeck_results = tcx.typeck(def);
|
let typeck_results = tcx.typeck(def);
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
let hir_id = tcx.local_def_id_to_hir_id(def);
|
let hir_id = tcx.local_def_id_to_hir_id(def);
|
||||||
|
@ -94,7 +96,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
BodyTy::Const(typeck_results.node_type(hir_id))
|
BodyTy::Const(typeck_results.node_type(hir_id))
|
||||||
};
|
};
|
||||||
|
|
||||||
Cx {
|
Self {
|
||||||
tcx,
|
tcx,
|
||||||
thir: Thir::new(body_type),
|
thir: Thir::new(body_type),
|
||||||
// FIXME(#132279): We're in a body, we should use a typing
|
// FIXME(#132279): We're in a body, we should use a typing
|
||||||
|
@ -113,7 +115,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||||
pat_from_hir(self.tcx, self.typing_env, self.typeck_results(), p)
|
pat_from_hir(self.tcx, self.typing_env, self.typeck_results, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {
|
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {
|
||||||
|
@ -197,15 +199,12 @@ impl<'tcx> Cx<'tcx> {
|
||||||
Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
|
Param { pat: Some(pat), ty, ty_span, self_kind, hir_id: Some(param.hir_id) }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for Cx<'tcx> {
|
fn user_args_applied_to_ty_of_hir_id(
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
&self,
|
||||||
self.tcx
|
hir_id: HirId,
|
||||||
}
|
) -> Option<ty::CanonicalUserType<'tcx>> {
|
||||||
|
crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
|
||||||
fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
|
|
||||||
self.typeck_results
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ use tracing::{debug, instrument};
|
||||||
pub(crate) use self::check_match::check_match;
|
pub(crate) use self::check_match::check_match;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
|
||||||
|
|
||||||
struct PatCtxt<'a, 'tcx> {
|
struct PatCtxt<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -540,16 +539,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
let e = match res {
|
let e = match res {
|
||||||
Res::Def(DefKind::ConstParam, def_id) => {
|
Res::Def(DefKind::ConstParam, def_id) => {
|
||||||
self.tcx.dcx().emit_err(ConstParamInPattern {
|
let const_span = self.tcx.def_span(def_id);
|
||||||
span,
|
self.tcx.dcx().emit_err(ConstParamInPattern { span, const_span })
|
||||||
const_span: self.tcx().def_span(def_id),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Static { .. }, def_id) => {
|
Res::Def(DefKind::Static { .. }, def_id) => {
|
||||||
self.tcx.dcx().emit_err(StaticInPattern {
|
let static_span = self.tcx.def_span(def_id);
|
||||||
span,
|
self.tcx.dcx().emit_err(StaticInPattern { span, static_span })
|
||||||
static_span: self.tcx().def_span(def_id),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => self.tcx.dcx().emit_err(NonConstPath { span }),
|
_ => self.tcx.dcx().emit_err(NonConstPath { span }),
|
||||||
};
|
};
|
||||||
|
@ -573,6 +568,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
kind
|
kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn user_args_applied_to_ty_of_hir_id(
|
||||||
|
&self,
|
||||||
|
hir_id: hir::HirId,
|
||||||
|
) -> Option<ty::CanonicalUserType<'tcx>> {
|
||||||
|
crate::thir::util::user_args_applied_to_ty_of_hir_id(self.typeck_results, hir_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Takes a HIR Path. If the path is a constant, evaluates it and feeds
|
/// Takes a HIR Path. If the path is a constant, evaluates it and feeds
|
||||||
/// it to `const_to_pat`. Any other path (like enum variants without fields)
|
/// it to `const_to_pat`. Any other path (like enum variants without fields)
|
||||||
/// is converted to the corresponding pattern via `lower_variant_or_leaf`.
|
/// is converted to the corresponding pattern via `lower_variant_or_leaf`.
|
||||||
|
@ -603,12 +605,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_provided_types = self.typeck_results().user_provided_types();
|
let user_provided_types = self.typeck_results.user_provided_types();
|
||||||
if let Some(&user_ty) = user_provided_types.get(id) {
|
if let Some(&user_ty) = user_provided_types.get(id) {
|
||||||
let annotation = CanonicalUserTypeAnnotation {
|
let annotation = CanonicalUserTypeAnnotation {
|
||||||
user_ty: Box::new(user_ty),
|
user_ty: Box::new(user_ty),
|
||||||
span,
|
span,
|
||||||
inferred_ty: self.typeck_results().node_type(id),
|
inferred_ty: self.typeck_results.node_type(id),
|
||||||
};
|
};
|
||||||
Box::new(Pat {
|
Box::new(Pat {
|
||||||
span,
|
span,
|
||||||
|
@ -672,13 +674,3 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
|
self.const_to_pat(constant, ct_ty, expr.hir_id, lit.span).kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UserAnnotatedTyHelpers<'tcx> for PatCtxt<'_, 'tcx> {
|
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
|
||||||
self.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
fn typeck_results(&self) -> &ty::TypeckResults<'tcx> {
|
|
||||||
self.typeck_results
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,33 +1,27 @@
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self, CanonicalUserType, TyCtxt};
|
use rustc_middle::ty::{self, CanonicalUserType};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
|
/// Looks up the type associated with this hir-id and applies the
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
/// user-given generic parameters; the hir-id must map to a suitable
|
||||||
|
/// type.
|
||||||
fn typeck_results(&self) -> &ty::TypeckResults<'tcx>;
|
pub(crate) fn user_args_applied_to_ty_of_hir_id<'tcx>(
|
||||||
|
typeck_results: &ty::TypeckResults<'tcx>,
|
||||||
/// Looks up the type associated with this hir-id and applies the
|
hir_id: hir::HirId,
|
||||||
/// user-given generic parameters; the hir-id must map to a suitable
|
) -> Option<CanonicalUserType<'tcx>> {
|
||||||
/// type.
|
let user_provided_types = typeck_results.user_provided_types();
|
||||||
fn user_args_applied_to_ty_of_hir_id(
|
let mut user_ty = *user_provided_types.get(hir_id)?;
|
||||||
&self,
|
debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
|
||||||
hir_id: hir::HirId,
|
let ty = typeck_results.node_type(hir_id);
|
||||||
) -> Option<CanonicalUserType<'tcx>> {
|
match ty.kind() {
|
||||||
let user_provided_types = self.typeck_results().user_provided_types();
|
ty::Adt(adt_def, ..) => {
|
||||||
let mut user_ty = *user_provided_types.get(hir_id)?;
|
if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
|
||||||
debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
|
*did = adt_def.did();
|
||||||
let ty = self.typeck_results().node_type(hir_id);
|
|
||||||
match ty.kind() {
|
|
||||||
ty::Adt(adt_def, ..) => {
|
|
||||||
if let ty::UserTypeKind::TypeOf(ref mut did, _) = &mut user_ty.value.kind {
|
|
||||||
*did = adt_def.did();
|
|
||||||
}
|
|
||||||
Some(user_ty)
|
|
||||||
}
|
}
|
||||||
ty::FnDef(..) => Some(user_ty),
|
Some(user_ty)
|
||||||
_ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty),
|
|
||||||
}
|
}
|
||||||
|
ty::FnDef(..) => Some(user_ty),
|
||||||
|
_ => bug!("ty: {:?} should not have user provided type {:?} recorded ", ty, user_ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
|
||||||
inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
|
inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::TyPat<'hir>) {
|
||||||
self.visit_pat(p)
|
intravisit::walk_ty_pat(self, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,7 +703,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
err.emit()
|
err.emit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,7 +805,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
"Async",
|
"Async",
|
||||||
);
|
);
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
return Some(err.emit());
|
return Some(err.emit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -852,7 +850,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
return Some(err.emit());
|
return Some(err.emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +865,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
kind: expected_kind.as_str(),
|
kind: expected_kind.as_str(),
|
||||||
});
|
});
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
return Some(err.emit());
|
return Some(err.emit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2826,7 +2822,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
|
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");
|
||||||
|
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
|
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
suggest_increasing_limit,
|
suggest_increasing_limit,
|
||||||
);
|
);
|
||||||
self.note_obligation_cause(&mut err, &obligation);
|
self.note_obligation_cause(&mut err, &obligation);
|
||||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
|
||||||
err.emit()
|
err.emit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1765,7 +1765,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
err.code(E0746);
|
err.code(E0746);
|
||||||
err.primary_message("return type cannot have an unboxed trait object");
|
err.primary_message("return type cannot be a trait object without pointer indirection");
|
||||||
err.children.clear();
|
err.children.clear();
|
||||||
|
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
|
@ -1781,25 +1781,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
("dyn ", span.shrink_to_lo())
|
("dyn ", span.shrink_to_lo())
|
||||||
};
|
};
|
||||||
let alternatively = if visitor
|
|
||||||
.returns
|
err.span_suggestion_verbose(
|
||||||
.iter()
|
impl_span,
|
||||||
.map(|expr| self.typeck_results.as_ref().unwrap().expr_ty_adjusted_opt(expr))
|
"consider returning an `impl Trait` instead of a `dyn Trait`",
|
||||||
.collect::<FxHashSet<_>>()
|
"impl ",
|
||||||
.len()
|
Applicability::MaybeIncorrect,
|
||||||
<= 1
|
);
|
||||||
{
|
|
||||||
err.span_suggestion_verbose(
|
|
||||||
impl_span,
|
|
||||||
"consider returning an `impl Trait` instead of a `dyn Trait`",
|
|
||||||
"impl ",
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
"alternatively, "
|
|
||||||
} else {
|
|
||||||
err.help("if there were a single returned type, you could use `impl Trait` instead");
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut sugg = vec![
|
let mut sugg = vec![
|
||||||
(span.shrink_to_lo(), format!("Box<{pre}")),
|
(span.shrink_to_lo(), format!("Box<{pre}")),
|
||||||
|
@ -1831,7 +1819,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
format!(
|
format!(
|
||||||
"{alternatively}box the return type, and wrap all of the returned values in \
|
"alternatively, box the return type, and wrap all of the returned values in \
|
||||||
`Box::new`",
|
`Box::new`",
|
||||||
),
|
),
|
||||||
sugg,
|
sugg,
|
||||||
|
@ -1841,41 +1829,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn point_at_returns_when_relevant(
|
|
||||||
&self,
|
|
||||||
err: &mut Diag<'_>,
|
|
||||||
obligation: &PredicateObligation<'tcx>,
|
|
||||||
) {
|
|
||||||
match obligation.cause.code().peel_derives() {
|
|
||||||
ObligationCauseCode::SizedReturnType => {}
|
|
||||||
_ => return,
|
|
||||||
}
|
|
||||||
|
|
||||||
let hir = self.tcx.hir();
|
|
||||||
let node = self.tcx.hir_node_by_def_id(obligation.cause.body_id);
|
|
||||||
if let hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::Fn { body: body_id, .. }, ..
|
|
||||||
}) = node
|
|
||||||
{
|
|
||||||
let body = hir.body(*body_id);
|
|
||||||
// Point at all the `return`s in the function as they have failed trait bounds.
|
|
||||||
let mut visitor = ReturnsVisitor::default();
|
|
||||||
visitor.visit_body(body);
|
|
||||||
let typeck_results = self.typeck_results.as_ref().unwrap();
|
|
||||||
for expr in &visitor.returns {
|
|
||||||
if let Some(returned_ty) = typeck_results.node_type_opt(expr.hir_id) {
|
|
||||||
let ty = self.resolve_vars_if_possible(returned_ty);
|
|
||||||
if ty.references_error() {
|
|
||||||
// don't print out the [type error] here
|
|
||||||
err.downgrade_to_delayed_bug();
|
|
||||||
} else {
|
|
||||||
err.span_label(expr.span, format!("this returned value is of type `{ty}`"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn report_closure_arg_mismatch(
|
pub(super) fn report_closure_arg_mismatch(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -4,19 +4,16 @@
|
||||||
//!
|
//!
|
||||||
//! [^1]: Formerly known as "object safety".
|
//! [^1]: Formerly known as "object safety".
|
||||||
|
|
||||||
use std::iter;
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use rustc_abi::BackendRepr;
|
|
||||||
use rustc_errors::FatalError;
|
use rustc_errors::FatalError;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt,
|
self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
|
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
|
||||||
TypeVisitableExt, TypeVisitor, TypingMode, Upcast,
|
|
||||||
};
|
};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_type_ir::elaborate;
|
use rustc_type_ir::elaborate;
|
||||||
|
@ -109,14 +106,6 @@ fn dyn_compatibility_violations_for_trait(
|
||||||
violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
|
violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans));
|
||||||
}
|
}
|
||||||
|
|
||||||
if violations.is_empty() {
|
|
||||||
for item in tcx.associated_items(trait_def_id).in_definition_order() {
|
|
||||||
if let ty::AssocKind::Fn = item.kind {
|
|
||||||
check_receiver_correct(tcx, trait_def_id, *item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
violations
|
violations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,55 +488,6 @@ fn virtual_call_violations_for_method<'tcx>(
|
||||||
errors
|
errors
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This code checks that `receiver_is_dispatchable` is correctly implemented.
|
|
||||||
///
|
|
||||||
/// This check is outlined from the dyn-compatibility check to avoid cycles with
|
|
||||||
/// layout computation, which relies on knowing whether methods are dyn-compatible.
|
|
||||||
fn check_receiver_correct<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, method: ty::AssocItem) {
|
|
||||||
if !is_vtable_safe_method(tcx, trait_def_id, method) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let method_def_id = method.def_id;
|
|
||||||
let sig = tcx.fn_sig(method_def_id).instantiate_identity();
|
|
||||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, method_def_id);
|
|
||||||
let receiver_ty = tcx.liberate_late_bound_regions(method_def_id, sig.input(0));
|
|
||||||
|
|
||||||
if receiver_ty == tcx.types.self_param {
|
|
||||||
// Assumed OK, may change later if unsized_locals permits `self: Self` as dispatchable.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// e.g., `Rc<()>`
|
|
||||||
let unit_receiver_ty = receiver_for_self_ty(tcx, receiver_ty, tcx.types.unit, method_def_id);
|
|
||||||
match tcx.layout_of(typing_env.as_query_input(unit_receiver_ty)).map(|l| l.backend_repr) {
|
|
||||||
Ok(BackendRepr::Scalar(..)) => (),
|
|
||||||
abi => {
|
|
||||||
tcx.dcx().span_delayed_bug(
|
|
||||||
tcx.def_span(method_def_id),
|
|
||||||
format!("receiver {unit_receiver_ty:?} when `Self = ()` should have a Scalar ABI; found {abi:?}"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let trait_object_ty = object_ty_for_trait(tcx, trait_def_id, tcx.lifetimes.re_static);
|
|
||||||
|
|
||||||
// e.g., `Rc<dyn Trait>`
|
|
||||||
let trait_object_receiver =
|
|
||||||
receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method_def_id);
|
|
||||||
match tcx.layout_of(typing_env.as_query_input(trait_object_receiver)).map(|l| l.backend_repr) {
|
|
||||||
Ok(BackendRepr::ScalarPair(..)) => (),
|
|
||||||
abi => {
|
|
||||||
tcx.dcx().span_delayed_bug(
|
|
||||||
tcx.def_span(method_def_id),
|
|
||||||
format!(
|
|
||||||
"receiver {trait_object_receiver:?} when `Self = {trait_object_ty}` should have a ScalarPair ABI; found {abi:?}"
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`.
|
/// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`.
|
||||||
/// For example, for `receiver_ty = Rc<Self>` and `self_ty = Foo`, returns `Rc<Foo>`.
|
/// For example, for `receiver_ty = Rc<Self>` and `self_ty = Foo`, returns `Rc<Foo>`.
|
||||||
fn receiver_for_self_ty<'tcx>(
|
fn receiver_for_self_ty<'tcx>(
|
||||||
|
@ -569,49 +509,6 @@ fn receiver_for_self_ty<'tcx>(
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the object type for the current trait. For example,
|
|
||||||
/// if the current trait is `Deref`, then this will be
|
|
||||||
/// `dyn Deref<Target = Self::Target> + 'static`.
|
|
||||||
#[instrument(level = "trace", skip(tcx), ret)]
|
|
||||||
fn object_ty_for_trait<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
trait_def_id: DefId,
|
|
||||||
lifetime: ty::Region<'tcx>,
|
|
||||||
) -> Ty<'tcx> {
|
|
||||||
let trait_ref = ty::TraitRef::identity(tcx, trait_def_id);
|
|
||||||
debug!(?trait_ref);
|
|
||||||
|
|
||||||
let trait_predicate = ty::Binder::dummy(ty::ExistentialPredicate::Trait(
|
|
||||||
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
|
|
||||||
));
|
|
||||||
debug!(?trait_predicate);
|
|
||||||
|
|
||||||
let pred: ty::Predicate<'tcx> = trait_ref.upcast(tcx);
|
|
||||||
let mut elaborated_predicates: Vec<_> = elaborate(tcx, [pred])
|
|
||||||
.filter_map(|pred| {
|
|
||||||
debug!(?pred);
|
|
||||||
let pred = pred.as_projection_clause()?;
|
|
||||||
Some(pred.map_bound(|p| {
|
|
||||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty(
|
|
||||||
tcx, p,
|
|
||||||
))
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
// NOTE: Since #37965, the existential predicates list has depended on the
|
|
||||||
// list of predicates to be sorted. This is mostly to enforce that the primary
|
|
||||||
// predicate comes first.
|
|
||||||
elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
|
||||||
elaborated_predicates.dedup();
|
|
||||||
|
|
||||||
let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(
|
|
||||||
iter::once(trait_predicate).chain(elaborated_predicates),
|
|
||||||
);
|
|
||||||
debug!(?existential_predicates);
|
|
||||||
|
|
||||||
Ty::new_dynamic(tcx, existential_predicates, lifetime, ty::Dyn)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks the method's receiver (the `self` argument) can be dispatched on when `Self` is a
|
/// Checks the method's receiver (the `self` argument) can be dispatched on when `Self` is a
|
||||||
/// trait object. We require that `DispatchableFromDyn` be implemented for the receiver type
|
/// trait object. We require that `DispatchableFromDyn` be implemented for the receiver type
|
||||||
/// in the following way:
|
/// in the following way:
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_hir::{
|
||||||
AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
|
AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
|
||||||
ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
|
ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
|
||||||
Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
|
Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
|
||||||
TraitBoundModifiers, Ty, TyKind,
|
TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
|
||||||
};
|
};
|
||||||
use rustc_lexer::{TokenKind, tokenize};
|
use rustc_lexer::{TokenKind, tokenize};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
|
@ -1102,6 +1102,22 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {
|
||||||
|
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
||||||
|
match pat.kind {
|
||||||
|
TyPatKind::Range(s, e, i) => {
|
||||||
|
if let Some(s) = s {
|
||||||
|
self.hash_const_arg(s);
|
||||||
|
}
|
||||||
|
if let Some(e) = e {
|
||||||
|
self.hash_const_arg(e);
|
||||||
|
}
|
||||||
|
std::mem::discriminant(&i).hash(&mut self.s);
|
||||||
|
},
|
||||||
|
TyPatKind::Err(_) => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
|
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
|
||||||
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
|
@ -1247,7 +1263,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
self.hash_ty(ty);
|
self.hash_ty(ty);
|
||||||
self.hash_pat(pat);
|
self.hash_ty_pat(pat);
|
||||||
},
|
},
|
||||||
TyKind::Ptr(mut_ty) => {
|
TyKind::Ptr(mut_ty) => {
|
||||||
self.hash_ty(mut_ty.ty);
|
self.hash_ty(mut_ty.ty);
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
//@ known-bug: rust-lang/rust#125810
|
|
||||||
#![feature(arbitrary_self_types, dispatch_from_dyn)]
|
|
||||||
|
|
||||||
use std::ops::{Deref, DispatchFromDyn};
|
|
||||||
|
|
||||||
trait Trait<T: Deref<Target = Self> + DispatchFromDyn<T>> {
|
|
||||||
fn MONO_BUF(self: T) -> dyn Trait<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,6 +0,0 @@
|
||||||
//@ known-bug: #134355
|
|
||||||
|
|
||||||
//@compile-flags: --crate-type=lib
|
|
||||||
fn digit() -> str {
|
|
||||||
return { i32::MIN };
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
//@ known-bug: #135124
|
|
||||||
trait A {
|
|
||||||
fn y(&self)
|
|
||||||
{
|
|
||||||
fn call() -> impl Sized {}
|
|
||||||
self.fold(call());
|
|
||||||
}
|
|
||||||
fn fold(&self, &self._) {}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
//@ known-bug: #90110
|
|
||||||
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{BufReader, BufRead};
|
|
||||||
use std::str::Split;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
pub trait Parser<D>
|
|
||||||
where dyn Parser<D>: Sized
|
|
||||||
{
|
|
||||||
fn new(split_header: Split<&str>) -> Self where Self: Sized;
|
|
||||||
fn parse_line(&self, split_line: &Split<&str>) -> D;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct CsvReader<D> {
|
|
||||||
parser: Box<dyn Parser<D>>,
|
|
||||||
|
|
||||||
reader: BufReader<File>,
|
|
||||||
buf: String, // Buffer we will read into. Avoids re-allocation on each line.
|
|
||||||
path: String, // Record this so we can return more informative error messages.
|
|
||||||
line: usize, // Same motivation for this.
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> CsvReader<D>
|
|
||||||
where dyn Parser<D>: Sized
|
|
||||||
{
|
|
||||||
fn new<F>(path: &str, make_parser: F) -> CsvReader<D>
|
|
||||||
where F: Fn(Split<char>) -> dyn Parser<D> {
|
|
||||||
let file = match File::open(Path::new(path)) {
|
|
||||||
Err(err) => panic!("Couldn't read {}: {}", path, err),
|
|
||||||
Ok(file) => file,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
|
|
||||||
let mut buf = String::new();
|
|
||||||
|
|
||||||
let parser = Box::new(match reader.read_line(&mut buf) {
|
|
||||||
Err(err) => panic!("Failed to read the header line from {}: {}", path, err),
|
|
||||||
Ok(_) => {
|
|
||||||
let split_header = buf.split(',');
|
|
||||||
make_parser(split_header)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
CsvReader {
|
|
||||||
parser: parser,
|
|
||||||
reader,
|
|
||||||
buf,
|
|
||||||
path: path.to_string(),
|
|
||||||
line: 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {}
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
//@ set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id"
|
//@ set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id"
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
/// Only core can do this
|
/// Only core can do this
|
||||||
impl i32 {
|
impl i32 {
|
||||||
//@ set identity = "$.index[*][?(@.docs=='Do Nothing')].id"
|
//@ set identity = "$.index[*][?(@.docs=='Do Nothing')].id"
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
// feature.
|
// feature.
|
||||||
|
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
/// ```{class="}
|
/// ```{class="}
|
||||||
/// main;
|
/// main;
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: unclosed quote string `"`
|
error: unclosed quote string `"`
|
||||||
--> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
|
--> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
|
||||||
|
|
|
|
||||||
LL | / /// ```{class="}
|
LL | / /// ```{class="}
|
||||||
LL | | /// main;
|
LL | | /// main;
|
||||||
|
@ -17,7 +17,7 @@ LL | #![deny(warnings)]
|
||||||
= note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
|
= note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]`
|
||||||
|
|
||||||
error: unclosed quote string `"`
|
error: unclosed quote string `"`
|
||||||
--> $DIR/custom_code_classes_in_docs-warning3.rs:8:1
|
--> $DIR/custom_code_classes_in_docs-warning3.rs:11:1
|
||||||
|
|
|
|
||||||
LL | / /// ```{class="}
|
LL | / /// ```{class="}
|
||||||
LL | | /// main;
|
LL | | /// main;
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#![feature(doc_cfg)]
|
#![feature(doc_cfg)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
|
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
//@ has 'foo/index.html'
|
//@ has 'foo/index.html'
|
||||||
//@ has - '//dt/*[@class="stab portability"]' 'foobar'
|
//@ has - '//dt/*[@class="stab portability"]' 'foobar'
|
||||||
//@ has - '//dt/*[@class="stab portability"]' 'bar'
|
//@ has - '//dt/*[@class="stab portability"]' 'bar'
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
//@ compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
|
//@ compile-flags: --extern-html-root-url=primitive_doc=../ -Z unstable-options
|
||||||
//@ only-linux
|
//@ only-linux
|
||||||
|
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
extern crate primitive_doc;
|
extern crate primitive_doc;
|
||||||
|
|
||||||
//@ has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'
|
//@ has 'cross_crate_primitive_doc/fn.foo.html' '//a[@href="../primitive_doc/primitive.usize.html"]' 'usize'
|
||||||
|
|
|
@ -6,8 +6,13 @@
|
||||||
#![rustc_coherence_is_core]
|
#![rustc_coherence_is_core]
|
||||||
#![crate_type = "rlib"]
|
#![crate_type = "rlib"]
|
||||||
|
|
||||||
|
|
||||||
//@ has no_doc_primitive/index.html
|
//@ has no_doc_primitive/index.html
|
||||||
//! A [`char`] and its [`char::len_utf8`].
|
//! A [`char`] and its [`char::len_utf8`].
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
impl char {
|
impl char {
|
||||||
pub fn len_utf8(self) -> usize {
|
pub fn len_utf8(self) -> usize {
|
||||||
42
|
42
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
// Regression test for <https://github.com/rust-lang/rust/issues/111064>.
|
// Regression test for <https://github.com/rust-lang/rust/issues/111064>.
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
//@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
|
//@ files "foo" "['sidebar-items.js', 'all.html', 'hidden', 'index.html', 'struct.Bar.html', \
|
||||||
// 'visible']"
|
// 'visible']"
|
||||||
//@ files "foo/hidden" "['inner']"
|
//@ files "foo/hidden" "['inner']"
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#![feature(intrinsics)]
|
#![feature(intrinsics)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core, lang_items)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
//@ has 'foo/fn.abort.html'
|
//@ has 'foo/fn.abort.html'
|
||||||
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
|
//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
|
||||||
#[rustc_intrinsic]
|
#[rustc_intrinsic]
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
|
|
||||||
--> $DIR/issue-58022.rs:4:25
|
|
||||||
|
|
|
||||||
LL | const SIZE: usize;
|
|
||||||
| ------------------ `Foo::SIZE` defined here
|
|
||||||
LL |
|
|
||||||
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
|
||||||
| ^^^^^^^^^ cannot refer to the associated constant of trait
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||||
--> $DIR/issue-58022.rs:13:41
|
--> $DIR/issue-58022.rs:13:41
|
||||||
|
|
|
|
||||||
|
@ -21,6 +12,15 @@ LL | pub struct Bar<T: ?Sized>(T);
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
|
||||||
|
--> $DIR/issue-58022.rs:4:25
|
||||||
|
|
|
||||||
|
LL | const SIZE: usize;
|
||||||
|
| ------------------ `Foo::SIZE` defined here
|
||||||
|
LL |
|
||||||
|
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
||||||
|
| ^^^^^^^^^ cannot refer to the associated constant of trait
|
||||||
|
|
||||||
error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
|
error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
|
||||||
--> $DIR/issue-58022.rs:15:9
|
--> $DIR/issue-58022.rs:15:9
|
||||||
|
|
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error[E0712]: thread-local variable borrowed past end of function
|
||||||
LL | assert_static(&FOO);
|
LL | assert_static(&FOO);
|
||||||
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
|
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
|
||||||
LL | }
|
LL | }
|
||||||
| - end of enclosing function is here
|
| - end of enclosing function is here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const ONE: [u16] = [1];
|
const ONE: [u16] = [1];
|
||||||
//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
|
//~^ ERROR the size for values of type `[u16]` cannot be known at compilation time
|
||||||
//~| ERROR the size for values of type `[u16]` cannot be known at compilation time
|
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
|
|
||||||
const TWO: &'static u16 = &ONE[0];
|
const TWO: &'static u16 = &ONE[0];
|
||||||
|
|
|
@ -12,22 +12,13 @@ error[E0308]: mismatched types
|
||||||
LL | const ONE: [u16] = [1];
|
LL | const ONE: [u16] = [1];
|
||||||
| ^^^ expected `[u16]`, found `[u16; 1]`
|
| ^^^ expected `[u16]`, found `[u16; 1]`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[u16]` cannot be known at compilation time
|
|
||||||
--> $DIR/const-slice-array-deref.rs:1:20
|
|
||||||
|
|
|
||||||
LL | const ONE: [u16] = [1];
|
|
||||||
| ^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `[u16]`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0161]: cannot move a value of type `[u16]`
|
error[E0161]: cannot move a value of type `[u16]`
|
||||||
--> $DIR/const-slice-array-deref.rs:6:28
|
--> $DIR/const-slice-array-deref.rs:5:28
|
||||||
|
|
|
|
||||||
LL | const TWO: &'static u16 = &ONE[0];
|
LL | const TWO: &'static u16 = &ONE[0];
|
||||||
| ^^^ the size of `[u16]` cannot be statically determined
|
| ^^^ the size of `[u16]` cannot be statically determined
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0161, E0277, E0308.
|
Some errors have detailed explanations: E0161, E0277, E0308.
|
||||||
For more information about an error, try `rustc --explain E0161`.
|
For more information about an error, try `rustc --explain E0161`.
|
||||||
|
|
|
@ -2,19 +2,19 @@ use std::fmt::Debug;
|
||||||
|
|
||||||
const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
|
const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
|
||||||
//~^ ERROR the size for values of type
|
//~^ ERROR the size for values of type
|
||||||
//~| ERROR the size for values of type
|
//~| ERROR cannot move out of a shared reference
|
||||||
|
|
||||||
const CONST_FOO: str = *"foo";
|
const CONST_FOO: str = *"foo";
|
||||||
//~^ ERROR the size for values of type
|
//~^ ERROR the size for values of type
|
||||||
//~| ERROR the size for values of type
|
//~| ERROR cannot move out of a shared reference
|
||||||
|
|
||||||
static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||||
//~^ ERROR the size for values of type
|
//~^ ERROR the size for values of type
|
||||||
//~| ERROR the size for values of type
|
//~| ERROR cannot move out of a shared reference
|
||||||
|
|
||||||
static STATIC_BAR: str = *"bar";
|
static STATIC_BAR: str = *"bar";
|
||||||
//~^ ERROR the size for values of type
|
//~^ ERROR the size for values of type
|
||||||
//~| ERROR the size for values of type
|
//~| ERROR cannot move out of a shared reference
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
|
println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR);
|
||||||
|
|
|
@ -6,15 +6,6 @@ LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
|
||||||
--> $DIR/const-unsized.rs:3:35
|
|
||||||
|
|
|
||||||
LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/const-unsized.rs:7:18
|
--> $DIR/const-unsized.rs:7:18
|
||||||
|
|
|
|
||||||
|
@ -23,15 +14,6 @@ LL | const CONST_FOO: str = *"foo";
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
|
||||||
--> $DIR/const-unsized.rs:7:24
|
|
||||||
|
|
|
||||||
LL | const CONST_FOO: str = *"foo";
|
|
||||||
| ^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/const-unsized.rs:11:18
|
--> $DIR/const-unsized.rs:11:18
|
||||||
|
|
|
|
||||||
|
@ -40,15 +22,6 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
|
||||||
--> $DIR/const-unsized.rs:11:37
|
|
||||||
|
|
|
||||||
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/const-unsized.rs:15:20
|
--> $DIR/const-unsized.rs:15:20
|
||||||
|
|
|
|
||||||
|
@ -57,14 +30,29 @@ LL | static STATIC_BAR: str = *"bar";
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0507]: cannot move out of a shared reference
|
||||||
|
--> $DIR/const-unsized.rs:3:35
|
||||||
|
|
|
||||||
|
LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait
|
||||||
|
|
||||||
|
error[E0507]: cannot move out of a shared reference
|
||||||
|
--> $DIR/const-unsized.rs:7:24
|
||||||
|
|
|
||||||
|
LL | const CONST_FOO: str = *"foo";
|
||||||
|
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
|
||||||
|
|
||||||
|
error[E0507]: cannot move out of a shared reference
|
||||||
|
--> $DIR/const-unsized.rs:11:37
|
||||||
|
|
|
||||||
|
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait
|
||||||
|
|
||||||
|
error[E0507]: cannot move out of a shared reference
|
||||||
--> $DIR/const-unsized.rs:15:26
|
--> $DIR/const-unsized.rs:15:26
|
||||||
|
|
|
|
||||||
LL | static STATIC_BAR: str = *"bar";
|
LL | static STATIC_BAR: str = *"bar";
|
||||||
| ^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0161]: cannot move a value of type `str`
|
error[E0161]: cannot move a value of type `str`
|
||||||
--> $DIR/const-unsized.rs:20:48
|
--> $DIR/const-unsized.rs:20:48
|
||||||
|
@ -80,5 +68,5 @@ LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATI
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0161, E0277.
|
Some errors have detailed explanations: E0161, E0277, E0507.
|
||||||
For more information about an error, try `rustc --explain E0161`.
|
For more information about an error, try `rustc --explain E0161`.
|
||||||
|
|
|
@ -9,11 +9,9 @@ const REF_INTERIOR_MUT: &usize = {
|
||||||
//~^ ERROR failed to resolve: use of undeclared type `AtomicUsize`
|
//~^ ERROR failed to resolve: use of undeclared type `AtomicUsize`
|
||||||
//~| WARN trait objects without an explicit `dyn` are deprecated
|
//~| WARN trait objects without an explicit `dyn` are deprecated
|
||||||
//~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
|
//~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
|
||||||
//~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
|
|
||||||
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
//~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||||
//~| HELP if this is a dyn-compatible trait, use `dyn`
|
//~| HELP if this is a dyn-compatible trait, use `dyn`
|
||||||
//~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
//~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
||||||
//~| HELP the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
|
||||||
unsafe { &*(&FOO as *const _ as *const usize) }
|
unsafe { &*(&FOO as *const _ as *const usize) }
|
||||||
};
|
};
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
|
@ -31,16 +31,7 @@ LL | static FOO: Sync = AtomicUsize::new(0);
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
--> $DIR/const_refs_to_static-ice-121413.rs:8:24
|
|
||||||
|
|
|
||||||
LL | static FOO: Sync = AtomicUsize::new(0);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0433.
|
Some errors have detailed explanations: E0277, E0433.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/E0746.rs:8:13
|
--> $DIR/E0746.rs:8:13
|
||||||
|
|
|
|
||||||
LL | fn foo() -> dyn Trait { Struct }
|
LL | fn foo() -> dyn Trait { Struct }
|
||||||
|
@ -13,7 +13,7 @@ help: alternatively, box the return type, and wrap all of the returned values in
|
||||||
LL | fn foo() -> Box<dyn Trait> { Box::new(Struct) }
|
LL | fn foo() -> Box<dyn Trait> { Box::new(Struct) }
|
||||||
| ++++ + +++++++++ +
|
| ++++ + +++++++++ +
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/E0746.rs:11:13
|
--> $DIR/E0746.rs:11:13
|
||||||
|
|
|
|
||||||
LL | fn bar() -> dyn Trait {
|
LL | fn bar() -> dyn Trait {
|
||||||
|
|
|
@ -8,6 +8,10 @@ error: unwinding panics are not supported without std
|
||||||
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
|
= note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
|
||||||
|
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/empty-extern-arg.rs:6:11
|
||||||
|
|
|
||||||
|
LL | fn main() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
20
tests/ui/fn/error-recovery-mismatch.rs
Normal file
20
tests/ui/fn/error-recovery-mismatch.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Used to ICE due to a size mismatch between the actual fake signature of `fold` and the
|
||||||
|
// generated signature used reporting the parameter mismatch at the call site.
|
||||||
|
// See issue #135124
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
fn y(&self)
|
||||||
|
{
|
||||||
|
fn call() -> impl Sized {}
|
||||||
|
self.fold(call(), call());
|
||||||
|
}
|
||||||
|
fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
//~^ ERROR unexpected `self` parameter in function
|
||||||
|
//~| ERROR expected one of `)` or `,`, found `.`
|
||||||
|
//~| ERROR identifier `self` is bound more than once in this parameter list
|
||||||
|
//~| WARNING anonymous parameters are deprecated
|
||||||
|
//~| WARNING this is accepted in the current edition
|
||||||
|
//~| ERROR the placeholder `_` is not allowed within types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
46
tests/ui/fn/error-recovery-mismatch.stderr
Normal file
46
tests/ui/fn/error-recovery-mismatch.stderr
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
error: unexpected `self` parameter in function
|
||||||
|
--> $DIR/error-recovery-mismatch.rs:11:29
|
||||||
|
|
|
||||||
|
LL | fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
| ^^^^^ must be the first parameter of an associated function
|
||||||
|
|
||||||
|
error: expected one of `)` or `,`, found `.`
|
||||||
|
--> $DIR/error-recovery-mismatch.rs:11:34
|
||||||
|
|
|
||||||
|
LL | fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
| ^
|
||||||
|
| |
|
||||||
|
| expected one of `)` or `,`
|
||||||
|
| help: missing `,`
|
||||||
|
|
||||||
|
error[E0415]: identifier `self` is bound more than once in this parameter list
|
||||||
|
--> $DIR/error-recovery-mismatch.rs:11:30
|
||||||
|
|
|
||||||
|
LL | fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
| ^^^^ used as parameter more than once
|
||||||
|
|
||||||
|
warning: anonymous parameters are deprecated and will be removed in the next edition
|
||||||
|
--> $DIR/error-recovery-mismatch.rs:11:35
|
||||||
|
|
|
||||||
|
LL | fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
| ^ help: try naming the parameter or explicitly ignoring it: `_: _`
|
||||||
|
|
|
||||||
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018!
|
||||||
|
= note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
|
||||||
|
= note: `#[warn(anonymous_parameters)]` on by default
|
||||||
|
|
||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
|
||||||
|
--> $DIR/error-recovery-mismatch.rs:11:35
|
||||||
|
|
|
||||||
|
LL | fn fold<T>(&self, _: T, &self._) {}
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
|
||||||
|
help: use type parameters instead
|
||||||
|
|
|
||||||
|
LL | fn fold<T, U>(&self, _: T, &self.U) {}
|
||||||
|
| +++ ~
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0121, E0415.
|
||||||
|
For more information about an error, try `rustc --explain E0121`.
|
10
tests/ui/fn/param-mismatch-trait-fn.rs
Normal file
10
tests/ui/fn/param-mismatch-trait-fn.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
trait Foo {
|
||||||
|
fn same_type<T>(_: T, _: T);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f<T: Foo, X, Y>(x: X, y: Y) {
|
||||||
|
T::same_type([x], Some(y));
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
23
tests/ui/fn/param-mismatch-trait-fn.stderr
Normal file
23
tests/ui/fn/param-mismatch-trait-fn.stderr
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/param-mismatch-trait-fn.rs:6:23
|
||||||
|
|
|
||||||
|
LL | T::same_type([x], Some(y));
|
||||||
|
| ------------ --- ^^^^^^^ expected `[X; 1]`, found `Option<Y>`
|
||||||
|
| | |
|
||||||
|
| | expected all arguments to be this `[X; 1]` type because they need to match the type of this parameter
|
||||||
|
| arguments to this function are incorrect
|
||||||
|
|
|
||||||
|
= note: expected array `[X; 1]`
|
||||||
|
found enum `Option<Y>`
|
||||||
|
note: associated function defined here
|
||||||
|
--> $DIR/param-mismatch-trait-fn.rs:2:8
|
||||||
|
|
|
||||||
|
LL | fn same_type<T>(_: T, _: T);
|
||||||
|
| ^^^^^^^^^ - - - this parameter needs to match the `[X; 1]` type of parameter #1
|
||||||
|
| | |
|
||||||
|
| | parameter #2 needs to match the `[X; 1]` type of this parameter
|
||||||
|
| parameter #1 and parameter #2 both reference this parameter `T`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -20,7 +20,7 @@ impl DynIncompatible for B {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn car() -> dyn DynIncompatible { //~ ERROR the trait `DynIncompatible` is not dyn compatible
|
fn car() -> dyn DynIncompatible { //~ ERROR the trait `DynIncompatible` is not dyn compatible
|
||||||
//~^ ERROR return type cannot have an unboxed trait object
|
//~^ ERROR return type cannot be a trait object without pointer indirection
|
||||||
if true {
|
if true {
|
||||||
return A;
|
return A;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,26 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
|
||||||
LL | fn foo() -> Self where Self: Sized;
|
LL | fn foo() -> Self where Self: Sized;
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
|
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:22:13
|
||||||
|
|
|
||||||
|
LL | fn car() -> dyn DynIncompatible {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
|
|
|
||||||
|
LL | fn car() -> impl DynIncompatible {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
||||||
|
LL ~ fn car() -> Box<dyn DynIncompatible> {
|
||||||
|
LL |
|
||||||
|
LL | if true {
|
||||||
|
LL ~ return Box::new(A);
|
||||||
|
LL | }
|
||||||
|
LL ~ Box::new(B)
|
||||||
|
|
|
||||||
|
|
||||||
error[E0038]: the trait `DynIncompatible` is not dyn compatible
|
error[E0038]: the trait `DynIncompatible` is not dyn compatible
|
||||||
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:30:17
|
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:30:17
|
||||||
|
|
|
|
||||||
|
@ -54,23 +74,6 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
|
||||||
LL | fn foo() -> Self where Self: Sized;
|
LL | fn foo() -> Self where Self: Sized;
|
||||||
| +++++++++++++++++
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
|
||||||
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:22:13
|
|
||||||
|
|
|
||||||
LL | fn car() -> dyn DynIncompatible {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: if there were a single returned type, you could use `impl Trait` instead
|
|
||||||
help: box the return type, and wrap all of the returned values in `Box::new`
|
|
||||||
|
|
|
||||||
LL ~ fn car() -> Box<dyn DynIncompatible> {
|
|
||||||
LL |
|
|
||||||
LL | if true {
|
|
||||||
LL ~ return Box::new(A);
|
|
||||||
LL | }
|
|
||||||
LL ~ Box::new(B)
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0038]: the trait `DynIncompatible` is not dyn compatible
|
error[E0038]: the trait `DynIncompatible` is not dyn compatible
|
||||||
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:32:16
|
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:32:16
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,9 +6,11 @@ impl Trait for u32 {}
|
||||||
|
|
||||||
fn fuz() -> (usize, Trait) { (42, Struct) }
|
fn fuz() -> (usize, Trait) { (42, Struct) }
|
||||||
//~^ ERROR E0277
|
//~^ ERROR E0277
|
||||||
|
//~| ERROR E0277
|
||||||
//~| ERROR E0308
|
//~| ERROR E0308
|
||||||
fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
||||||
//~^ ERROR E0277
|
//~^ ERROR E0277
|
||||||
|
//~| ERROR E0277
|
||||||
//~| ERROR E0308
|
//~| ERROR E0308
|
||||||
fn bap() -> Trait { Struct }
|
fn bap() -> Trait { Struct }
|
||||||
//~^ ERROR E0746
|
//~^ ERROR E0746
|
||||||
|
|
|
@ -1,49 +1,25 @@
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35
|
|
||||||
|
|
|
||||||
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
|
||||||
| ^^^^^^ expected `dyn Trait`, found `Struct`
|
|
||||||
|
|
|
||||||
= note: expected trait object `(dyn Trait + 'static)`
|
|
||||||
found struct `Struct`
|
|
||||||
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13
|
||||||
|
|
|
|
||||||
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
||||||
| ^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
|
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| doesn't have a size known at compile-time
|
|
||||||
|
|
|
|
||||||
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
||||||
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39
|
|
||||||
|
|
|
||||||
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
|
||||||
| ^^^^^^ expected `dyn Trait`, found `Struct`
|
|
||||||
|
|
|
||||||
= note: expected trait object `(dyn Trait + 'static)`
|
|
||||||
found struct `Struct`
|
|
||||||
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:13
|
||||||
|
|
|
|
||||||
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
||||||
| ^^^^^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))`
|
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
| |
|
|
||||||
| doesn't have a size known at compile-time
|
|
||||||
|
|
|
|
||||||
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
||||||
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
|
||||||
|
|
|
|
||||||
LL | fn bap() -> Trait { Struct }
|
LL | fn bap() -> Trait { Struct }
|
||||||
| ^^^^^ doesn't have a size known at compile-time
|
| ^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -57,8 +33,8 @@ help: alternatively, box the return type, and wrap all of the returned values in
|
||||||
LL | fn bap() -> Box<dyn Trait> { Box::new(Struct) }
|
LL | fn bap() -> Box<dyn Trait> { Box::new(Struct) }
|
||||||
| +++++++ + +++++++++ +
|
| +++++++ + +++++++++ +
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
|
||||||
|
|
|
|
||||||
LL | fn ban() -> dyn Trait { Struct }
|
LL | fn ban() -> dyn Trait { Struct }
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -72,8 +48,8 @@ help: alternatively, box the return type, and wrap all of the returned values in
|
||||||
LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
|
LL | fn ban() -> Box<dyn Trait> { Box::new(Struct) }
|
||||||
| ++++ + +++++++++ +
|
| ++++ + +++++++++ +
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
|
||||||
|
|
|
|
||||||
LL | fn bak() -> dyn Trait { unimplemented!() }
|
LL | fn bak() -> dyn Trait { unimplemented!() }
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -87,14 +63,17 @@ help: alternatively, box the return type, and wrap all of the returned values in
|
||||||
LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
|
LL | fn bak() -> Box<dyn Trait> { Box::new(unimplemented!()) }
|
||||||
| ++++ + +++++++++ +
|
| ++++ + +++++++++ +
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13
|
||||||
|
|
|
|
||||||
LL | fn bal() -> dyn Trait {
|
LL | fn bal() -> dyn Trait {
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: if there were a single returned type, you could use `impl Trait` instead
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
help: box the return type, and wrap all of the returned values in `Box::new`
|
|
|
||||||
|
LL | fn bal() -> impl Trait {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
|
||||||
LL ~ fn bal() -> Box<dyn Trait> {
|
LL ~ fn bal() -> Box<dyn Trait> {
|
||||||
LL | if true {
|
LL | if true {
|
||||||
|
@ -103,14 +82,17 @@ LL | }
|
||||||
LL ~ Box::new(42)
|
LL ~ Box::new(42)
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13
|
||||||
|
|
|
|
||||||
LL | fn bax() -> dyn Trait {
|
LL | fn bax() -> dyn Trait {
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
|
||||||
= help: if there were a single returned type, you could use `impl Trait` instead
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
help: box the return type, and wrap all of the returned values in `Box::new`
|
|
|
||||||
|
LL | fn bax() -> impl Trait {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
|
||||||
LL ~ fn bax() -> Box<dyn Trait> {
|
LL ~ fn bax() -> Box<dyn Trait> {
|
||||||
LL | if true {
|
LL | if true {
|
||||||
|
@ -119,144 +101,8 @@ LL | } else {
|
||||||
LL ~ Box::new(42)
|
LL ~ Box::new(42)
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:34:16
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:62:13
|
||||||
|
|
|
||||||
LL | fn bam() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
LL | if true {
|
|
||||||
LL | return Struct;
|
|
||||||
| ^^^^^^ expected `Box<dyn Trait>`, found `Struct`
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found struct `Struct`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | return Box::new(Struct);
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5
|
|
||||||
|
|
|
||||||
LL | fn bam() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
...
|
|
||||||
LL | 42
|
|
||||||
| ^^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(42)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16
|
|
||||||
|
|
|
||||||
LL | fn baq() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
LL | if true {
|
|
||||||
LL | return 0;
|
|
||||||
| ^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | return Box::new(0);
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5
|
|
||||||
|
|
|
||||||
LL | fn baq() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
...
|
|
||||||
LL | 42
|
|
||||||
| ^^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(42)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
|
|
||||||
|
|
|
||||||
LL | fn baz() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
LL | if true {
|
|
||||||
LL | Struct
|
|
||||||
| ^^^^^^ expected `Box<dyn Trait>`, found `Struct`
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found struct `Struct`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(Struct)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
|
|
||||||
|
|
|
||||||
LL | fn baz() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
...
|
|
||||||
LL | 42
|
|
||||||
| ^^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(42)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
|
|
||||||
|
|
|
||||||
LL | fn baw() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
LL | if true {
|
|
||||||
LL | 0
|
|
||||||
| ^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(0)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
|
|
||||||
|
|
|
||||||
LL | fn baw() -> Box<dyn Trait> {
|
|
||||||
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
|
||||||
...
|
|
||||||
LL | 42
|
|
||||||
| ^^ expected `Box<dyn Trait>`, found integer
|
|
||||||
|
|
|
||||||
= note: expected struct `Box<(dyn Trait + 'static)>`
|
|
||||||
found type `{integer}`
|
|
||||||
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
|
||||||
help: store this in the heap by calling `Box::new`
|
|
||||||
|
|
|
||||||
LL | Box::new(42)
|
|
||||||
| +++++++++ +
|
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13
|
|
||||||
|
|
|
|
||||||
LL | fn bat() -> dyn Trait {
|
LL | fn bat() -> dyn Trait {
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -274,8 +120,8 @@ LL | }
|
||||||
LL ~ Box::new(42)
|
LL ~ Box::new(42)
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:66:13
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:68:13
|
||||||
|
|
|
|
||||||
LL | fn bay() -> dyn Trait {
|
LL | fn bay() -> dyn Trait {
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -293,7 +139,183 @@ LL | } else {
|
||||||
LL ~ Box::new(42)
|
LL ~ Box::new(42)
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 19 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35
|
||||||
|
|
|
||||||
|
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
||||||
|
| ^^^^^^ expected `dyn Trait`, found `Struct`
|
||||||
|
|
|
||||||
|
= note: expected trait object `(dyn Trait + 'static)`
|
||||||
|
found struct `Struct`
|
||||||
|
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:30
|
||||||
|
|
|
||||||
|
LL | fn fuz() -> (usize, Trait) { (42, Struct) }
|
||||||
|
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
||||||
|
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
||||||
|
= note: tuples must have a statically known size to be initialized
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:39
|
||||||
|
|
|
||||||
|
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
||||||
|
| ^^^^^^ expected `dyn Trait`, found `Struct`
|
||||||
|
|
|
||||||
|
= note: expected trait object `(dyn Trait + 'static)`
|
||||||
|
found struct `Struct`
|
||||||
|
= help: `Struct` implements `Trait` so you could box the found value and coerce it to the trait object `Box<dyn Trait>`, you will have to change the expected type as well
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:11:34
|
||||||
|
|
|
||||||
|
LL | fn bar() -> (usize, dyn Trait) { (42, Struct) }
|
||||||
|
| ^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: within `(usize, (dyn Trait + 'static))`, the trait `Sized` is not implemented for `(dyn Trait + 'static)`
|
||||||
|
= note: required because it appears within the type `(usize, (dyn Trait + 'static))`
|
||||||
|
= note: tuples must have a statically known size to be initialized
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:16
|
||||||
|
|
|
||||||
|
LL | fn bam() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
LL | if true {
|
||||||
|
LL | return Struct;
|
||||||
|
| ^^^^^^ expected `Box<dyn Trait>`, found `Struct`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found struct `Struct`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | return Box::new(Struct);
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:38:5
|
||||||
|
|
|
||||||
|
LL | fn bam() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
...
|
||||||
|
LL | 42
|
||||||
|
| ^^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(42)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:16
|
||||||
|
|
|
||||||
|
LL | fn baq() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
LL | if true {
|
||||||
|
LL | return 0;
|
||||||
|
| ^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | return Box::new(0);
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:44:5
|
||||||
|
|
|
||||||
|
LL | fn baq() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
...
|
||||||
|
LL | 42
|
||||||
|
| ^^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(42)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
|
||||||
|
|
|
||||||
|
LL | fn baz() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
LL | if true {
|
||||||
|
LL | Struct
|
||||||
|
| ^^^^^^ expected `Box<dyn Trait>`, found `Struct`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found struct `Struct`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(Struct)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:50:9
|
||||||
|
|
|
||||||
|
LL | fn baz() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
...
|
||||||
|
LL | 42
|
||||||
|
| ^^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(42)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
|
||||||
|
|
|
||||||
|
LL | fn baw() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
LL | if true {
|
||||||
|
LL | 0
|
||||||
|
| ^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(0)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/dyn-trait-return-should-be-impl-trait.rs:57:9
|
||||||
|
|
|
||||||
|
LL | fn baw() -> Box<dyn Trait> {
|
||||||
|
| -------------- expected `Box<(dyn Trait + 'static)>` because of return type
|
||||||
|
...
|
||||||
|
LL | 42
|
||||||
|
| ^^ expected `Box<dyn Trait>`, found integer
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<(dyn Trait + 'static)>`
|
||||||
|
found type `{integer}`
|
||||||
|
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
|
||||||
|
help: store this in the heap by calling `Box::new`
|
||||||
|
|
|
||||||
|
LL | Box::new(42)
|
||||||
|
| +++++++++ +
|
||||||
|
|
||||||
|
error: aborting due to 21 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308, E0746.
|
Some errors have detailed explanations: E0277, E0308, E0746.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -63,7 +63,7 @@ fn dog() -> impl std::fmt::Display {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
|
fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
|
||||||
match 13 {
|
match 13 {
|
||||||
0 => {
|
0 => {
|
||||||
return 0i32;
|
return 0i32;
|
||||||
|
@ -74,7 +74,7 @@ fn hat() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
|
fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
|
||||||
match 13 {
|
match 13 {
|
||||||
0 => 0i32,
|
0 => 0i32,
|
||||||
1 => 1u32,
|
1 => 1u32,
|
||||||
|
@ -82,7 +82,7 @@ fn pug() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn man() -> dyn std::fmt::Display { //~ ERROR return type cannot have an unboxed trait object
|
fn man() -> dyn std::fmt::Display { //~ ERROR return type cannot be a trait object without pointer indirection
|
||||||
if false {
|
if false {
|
||||||
0i32
|
0i32
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,3 +1,62 @@
|
||||||
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
|
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
|
||||||
|
|
|
||||||
|
LL | fn hat() -> dyn std::fmt::Display {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
|
|
|
||||||
|
LL | fn hat() -> impl std::fmt::Display {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
||||||
|
LL ~ fn hat() -> Box<dyn std::fmt::Display> {
|
||||||
|
LL | match 13 {
|
||||||
|
LL | 0 => {
|
||||||
|
LL ~ return Box::new(0i32);
|
||||||
|
LL | }
|
||||||
|
LL | _ => {
|
||||||
|
LL ~ Box::new(1u32)
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
|
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
|
||||||
|
|
|
||||||
|
LL | fn pug() -> dyn std::fmt::Display {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
|
|
|
||||||
|
LL | fn pug() -> impl std::fmt::Display {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
||||||
|
LL ~ fn pug() -> Box<dyn std::fmt::Display> {
|
||||||
|
LL | match 13 {
|
||||||
|
LL ~ 0 => Box::new(0i32),
|
||||||
|
LL ~ 1 => Box::new(1u32),
|
||||||
|
LL ~ _ => Box::new(2u32),
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
|
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
|
||||||
|
|
|
||||||
|
LL | fn man() -> dyn std::fmt::Display {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
||||||
|
|
|
||||||
|
LL | fn man() -> impl std::fmt::Display {
|
||||||
|
| ~~~~
|
||||||
|
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
||||||
|
|
|
||||||
|
LL ~ fn man() -> Box<dyn std::fmt::Display> {
|
||||||
|
LL | if false {
|
||||||
|
LL ~ Box::new(0i32)
|
||||||
|
LL | } else {
|
||||||
|
LL ~ Box::new(1u32)
|
||||||
|
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
|
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
|
||||||
|
|
|
|
||||||
|
@ -165,62 +224,6 @@ help: change the type of the numeric literal from `u32` to `i32`
|
||||||
LL | 1i32
|
LL | 1i32
|
||||||
| ~~~
|
| ~~~
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
|
||||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
|
|
||||||
|
|
|
||||||
LL | fn hat() -> dyn std::fmt::Display {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
|
||||||
|
|
|
||||||
LL | fn hat() -> impl std::fmt::Display {
|
|
||||||
| ~~~~
|
|
||||||
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
|
||||||
|
|
|
||||||
LL ~ fn hat() -> Box<dyn std::fmt::Display> {
|
|
||||||
LL | match 13 {
|
|
||||||
LL | 0 => {
|
|
||||||
LL ~ return Box::new(0i32);
|
|
||||||
LL | }
|
|
||||||
LL | _ => {
|
|
||||||
LL ~ Box::new(1u32)
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
|
||||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
|
|
||||||
|
|
|
||||||
LL | fn pug() -> dyn std::fmt::Display {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
help: consider returning an `impl Trait` instead of a `dyn Trait`
|
|
||||||
|
|
|
||||||
LL | fn pug() -> impl std::fmt::Display {
|
|
||||||
| ~~~~
|
|
||||||
help: alternatively, box the return type, and wrap all of the returned values in `Box::new`
|
|
||||||
|
|
|
||||||
LL ~ fn pug() -> Box<dyn std::fmt::Display> {
|
|
||||||
LL | match 13 {
|
|
||||||
LL ~ 0 => Box::new(0i32),
|
|
||||||
LL ~ 1 => Box::new(1u32),
|
|
||||||
LL ~ _ => Box::new(2u32),
|
|
||||||
|
|
|
||||||
|
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
|
||||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13
|
|
||||||
|
|
|
||||||
LL | fn man() -> dyn std::fmt::Display {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: if there were a single returned type, you could use `impl Trait` instead
|
|
||||||
help: box the return type, and wrap all of the returned values in `Box::new`
|
|
||||||
|
|
|
||||||
LL ~ fn man() -> Box<dyn std::fmt::Display> {
|
|
||||||
LL | if false {
|
|
||||||
LL ~ Box::new(0i32)
|
|
||||||
LL | } else {
|
|
||||||
LL ~ Box::new(1u32)
|
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0308, E0746.
|
Some errors have detailed explanations: E0308, E0746.
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | let a = &FOO;
|
||||||
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
|
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - end of enclosing function is here
|
| - end of enclosing function is here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ pub trait AbstractRenderer {}
|
||||||
|
|
||||||
fn _create_render(_: &()) ->
|
fn _create_render(_: &()) ->
|
||||||
dyn AbstractRenderer
|
dyn AbstractRenderer
|
||||||
//~^ ERROR return type cannot have an unboxed trait object
|
//~^ ERROR return type cannot be a trait object without pointer indirection
|
||||||
{
|
{
|
||||||
match 0 {
|
match 0 {
|
||||||
_ => unimplemented!()
|
_ => unimplemented!()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0746]: return type cannot have an unboxed trait object
|
error[E0746]: return type cannot be a trait object without pointer indirection
|
||||||
--> $DIR/issue-18107.rs:4:5
|
--> $DIR/issue-18107.rs:4:5
|
||||||
|
|
|
|
||||||
LL | dyn AbstractRenderer
|
LL | dyn AbstractRenderer
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct Struct {
|
||||||
|
|
||||||
fn new_struct(
|
fn new_struct(
|
||||||
r: dyn A + 'static //~ ERROR the size for values of type
|
r: dyn A + 'static //~ ERROR the size for values of type
|
||||||
) -> Struct {
|
) -> Struct { //~ ERROR the size for values of type
|
||||||
Struct { r: r }
|
Struct { r: r }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-5883.rs:9:6
|
||||||
|
|
|
||||||
|
LL | ) -> Struct {
|
||||||
|
| ^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: within `Struct`, the trait `Sized` is not implemented for `(dyn A + 'static)`
|
||||||
|
note: required because it appears within the type `Struct`
|
||||||
|
--> $DIR/issue-5883.rs:3:8
|
||||||
|
|
|
||||||
|
LL | struct Struct {
|
||||||
|
| ^^^^^^
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/issue-5883.rs:8:8
|
--> $DIR/issue-5883.rs:8:8
|
||||||
|
|
|
|
||||||
|
@ -15,6 +29,6 @@ help: function arguments must have a statically known size, borrowed types alway
|
||||||
LL | r: &dyn A + 'static
|
LL | r: &dyn A + 'static
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/lang-item-missing.rs:11:60
|
||||||
|
|
|
||||||
|
LL | extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
|
||||||
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ note: method defined here
|
||||||
--> $DIR/issue-61525.rs:2:8
|
--> $DIR/issue-61525.rs:2:8
|
||||||
|
|
|
|
||||||
LL | fn query<Q>(self, q: Q);
|
LL | fn query<Q>(self, q: Q);
|
||||||
| ^^^^^
|
| ^^^^^ -
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -14,16 +14,20 @@ mod bar {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn foo() {}
|
pub fn foo() {}
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
|
|
||||||
fn test1() {
|
fn test1() {
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
use bar::foo;
|
use bar::foo;
|
||||||
//~^ ERROR unresolved import `bar::foo` [E0432]
|
//~^ ERROR unresolved import `bar::foo` [E0432]
|
||||||
//~| no `foo` in `bar`
|
//~| no `foo` in `bar`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2() {
|
fn test2() {
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
use bar::glob::foo;
|
use bar::glob::foo;
|
||||||
//~^ ERROR `foo` is private
|
//~^ ERROR `foo` is private
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0432]: unresolved import `bar::foo`
|
error[E0432]: unresolved import `bar::foo`
|
||||||
--> $DIR/privacy2.rs:19:9
|
--> $DIR/privacy2.rs:21:9
|
||||||
|
|
|
|
||||||
LL | use bar::foo;
|
LL | use bar::foo;
|
||||||
| ^^^^^^^^ no `foo` in `bar`
|
| ^^^^^^^^ no `foo` in `bar`
|
||||||
|
|
||||||
error[E0603]: function import `foo` is private
|
error[E0603]: function import `foo` is private
|
||||||
--> $DIR/privacy2.rs:25:20
|
--> $DIR/privacy2.rs:28:20
|
||||||
|
|
|
|
||||||
LL | use bar::glob::foo;
|
LL | use bar::glob::foo;
|
||||||
| ^^^ private function import
|
| ^^^ private function import
|
||||||
|
@ -22,8 +22,40 @@ LL | pub fn foo() {}
|
||||||
| ^^^^^^^^^^^^ you could import this directly
|
| ^^^^^^^^^^^^ you could import this directly
|
||||||
|
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy2.rs:16:14
|
||||||
|
|
|
||||||
|
LL | pub fn foo() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy2.rs:19:12
|
||||||
|
|
|
||||||
|
LL | fn test1() {
|
||||||
|
| ____________^
|
||||||
|
LL | |
|
||||||
|
LL | | use bar::foo;
|
||||||
|
... |
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy2.rs:26:12
|
||||||
|
|
|
||||||
|
LL | fn test2() {
|
||||||
|
| ____________^
|
||||||
|
LL | |
|
||||||
|
LL | | use bar::glob::foo;
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy2.rs:32:11
|
||||||
|
|
|
||||||
|
LL | fn main() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0432, E0603.
|
Some errors have detailed explanations: E0432, E0603.
|
||||||
For more information about an error, try `rustc --explain E0432`.
|
For more information about an error, try `rustc --explain E0432`.
|
||||||
|
|
|
@ -11,12 +11,15 @@ mod bar {
|
||||||
|
|
||||||
mod glob {
|
mod glob {
|
||||||
fn gpriv() {}
|
fn gpriv() {}
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn foo() {}
|
pub fn foo() {}
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
|
|
||||||
fn test1() {
|
fn test1() {
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
use bar::gpriv;
|
use bar::gpriv;
|
||||||
//~^ ERROR unresolved import `bar::gpriv` [E0432]
|
//~^ ERROR unresolved import `bar::gpriv` [E0432]
|
||||||
//~| no `gpriv` in `bar`
|
//~| no `gpriv` in `bar`
|
||||||
|
@ -27,3 +30,4 @@ fn test1() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
//~^ ERROR requires `sized` lang_item
|
||||||
|
|
|
@ -1,11 +1,39 @@
|
||||||
error[E0432]: unresolved import `bar::gpriv`
|
error[E0432]: unresolved import `bar::gpriv`
|
||||||
--> $DIR/privacy3.rs:20:9
|
--> $DIR/privacy3.rs:23:9
|
||||||
|
|
|
|
||||||
LL | use bar::gpriv;
|
LL | use bar::gpriv;
|
||||||
| ^^^^^^^^^^ no `gpriv` in `bar`
|
| ^^^^^^^^^^ no `gpriv` in `bar`
|
||||||
|
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy3.rs:18:14
|
||||||
|
|
|
||||||
|
LL | pub fn foo() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy3.rs:21:12
|
||||||
|
|
|
||||||
|
LL | fn test1() {
|
||||||
|
| ____________^
|
||||||
|
LL | |
|
||||||
|
LL | | use bar::gpriv;
|
||||||
|
... |
|
||||||
|
LL | | gpriv();
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
||||||
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy3.rs:32:11
|
||||||
|
|
|
||||||
|
LL | fn main() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/privacy3.rs:13:20
|
||||||
|
|
|
||||||
|
LL | fn gpriv() {}
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0432`.
|
For more information about this error, try `rustc --explain E0432`.
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
error: requires `sized` lang_item
|
error: requires `sized` lang_item
|
||||||
|
--> $DIR/issue-59191-replace-root-with-fn.rs:9:1
|
||||||
|
|
|
||||||
|
LL | #![issue_59191::no_main]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in the attribute macro `issue_59191::no_main` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
16
tests/ui/self/dispatch-from-dyn-layout-2.rs
Normal file
16
tests/ui/self/dispatch-from-dyn-layout-2.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//@ check-pass
|
||||||
|
// Regression test for #90110.
|
||||||
|
|
||||||
|
// Make sure that object safety checking doesn't freak out when
|
||||||
|
// we have impossible-to-satisfy `Sized` predicates.
|
||||||
|
|
||||||
|
trait Parser
|
||||||
|
where
|
||||||
|
for<'a> (dyn Parser + 'a): Sized,
|
||||||
|
{
|
||||||
|
fn parse_line(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: &dyn Parser) {}
|
||||||
|
|
||||||
|
fn main() {}
|
19
tests/ui/self/dispatch-from-dyn-layout-3.rs
Normal file
19
tests/ui/self/dispatch-from-dyn-layout-3.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Make sure that object safety checking doesn't freak out when
|
||||||
|
// we have impossible-to-satisfy `DispatchFromDyn` predicates.
|
||||||
|
|
||||||
|
#![feature(dispatch_from_dyn)]
|
||||||
|
#![feature(arbitrary_self_types)]
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::ops::DispatchFromDyn;
|
||||||
|
|
||||||
|
trait Trait<T: Deref<Target = Self>>
|
||||||
|
where
|
||||||
|
for<'a> &'a T: DispatchFromDyn<&'a T>,
|
||||||
|
{
|
||||||
|
fn foo(self: &T) -> Box<dyn Trait<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,4 +1,8 @@
|
||||||
//@ known-bug: #57276
|
//@ check-pass
|
||||||
|
// Regression test for #57276.
|
||||||
|
|
||||||
|
// Make sure that object safety checking doesn't freak out when
|
||||||
|
// we have impossible-to-satisfy `DispatchFromDyn` predicates.
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, dispatch_from_dyn)]
|
#![feature(arbitrary_self_types, dispatch_from_dyn)]
|
||||||
|
|
|
@ -2,7 +2,6 @@ fn main() {
|
||||||
static foo: dyn Fn() -> u32 = || -> u32 {
|
static foo: dyn Fn() -> u32 = || -> u32 {
|
||||||
//~^ ERROR the size for values of type
|
//~^ ERROR the size for values of type
|
||||||
//~| ERROR cannot be shared between threads safely
|
//~| ERROR cannot be shared between threads safely
|
||||||
//~| ERROR the size for values of type
|
|
||||||
//~| ERROR mismatched types
|
//~| ERROR mismatched types
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,33 +15,19 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||||
|
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time
|
|
||||||
--> $DIR/issue-24446.rs:2:35
|
|
||||||
|
|
|
||||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
|
||||||
| ___________________________________^
|
|
||||||
... |
|
|
||||||
LL | | 0
|
|
||||||
LL | | };
|
|
||||||
| |_____^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-24446.rs:2:35
|
--> $DIR/issue-24446.rs:2:35
|
||||||
|
|
|
|
||||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||||
| ___________________________________^
|
| ___________________________________^
|
||||||
... |
|
... |
|
||||||
LL | | 0
|
|
||||||
LL | | };
|
LL | | };
|
||||||
| |_____^ expected `dyn Fn`, found closure
|
| |_____^ expected `dyn Fn`, found closure
|
||||||
|
|
|
|
||||||
= note: expected trait object `(dyn Fn() -> u32 + 'static)`
|
= note: expected trait object `(dyn Fn() -> u32 + 'static)`
|
||||||
found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}`
|
found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0277, E0308.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -11,6 +11,12 @@ note: required because it appears within the type `Foo`
|
||||||
LL | pub struct Foo {
|
LL | pub struct Foo {
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/unsized_type2.rs:14:45
|
||||||
|
|
|
||||||
|
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||||
|
| ^ expected `str`, found integer
|
||||||
|
|
||||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
--> $DIR/unsized_type2.rs:14:30
|
--> $DIR/unsized_type2.rs:14:30
|
||||||
|
|
|
|
||||||
|
@ -23,13 +29,7 @@ note: required because it appears within the type `Foo`
|
||||||
|
|
|
|
||||||
LL | pub struct Foo {
|
LL | pub struct Foo {
|
||||||
| ^^^
|
| ^^^
|
||||||
= note: constant expressions must have a statically known size
|
= note: structs must have a statically known size to be initialized
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/unsized_type2.rs:14:45
|
|
||||||
|
|
|
||||||
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
|
||||||
| ^ expected `str`, found integer
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,18 @@ LL | trait Other: Sized {}
|
||||||
| |
|
| |
|
||||||
| this trait is not dyn compatible...
|
| this trait is not dyn compatible...
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||||
|
--> $DIR/dyn-incompatible-trait-references-self.rs:4:22
|
||||||
|
|
|
||||||
|
LL | fn bat(&self) -> Self {}
|
||||||
|
| ^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
help: consider further restricting `Self`
|
||||||
|
|
|
||||||
|
LL | fn bat(&self) -> Self where Self: Sized {}
|
||||||
|
| +++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||||
--> $DIR/dyn-incompatible-trait-references-self.rs:2:22
|
--> $DIR/dyn-incompatible-trait-references-self.rs:2:22
|
||||||
|
|
|
|
||||||
|
@ -61,18 +73,6 @@ LL | fn bat(&self) -> Self {}
|
||||||
= note: expected type parameter `Self`
|
= note: expected type parameter `Self`
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
|
||||||
--> $DIR/dyn-incompatible-trait-references-self.rs:4:22
|
|
||||||
|
|
|
||||||
LL | fn bat(&self) -> Self {}
|
|
||||||
| ^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= note: the return type of a function must have a statically known size
|
|
||||||
help: consider further restricting `Self`
|
|
||||||
|
|
|
||||||
LL | fn bat(&self) -> Self where Self: Sized {}
|
|
||||||
| +++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0038, E0277, E0308.
|
Some errors have detailed explanations: E0038, E0277, E0308.
|
||||||
|
|
|
@ -94,7 +94,7 @@ note: method defined here
|
||||||
--> $DIR/trait-with-missing-associated-type-restriction.rs:9:8
|
--> $DIR/trait-with-missing-associated-type-restriction.rs:9:8
|
||||||
|
|
|
|
||||||
LL | fn funk(&self, _: Self::A);
|
LL | fn funk(&self, _: Self::A);
|
||||||
| ^^^^
|
| ^^^^ -
|
||||||
help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
|
help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
|
||||||
|
|
|
|
||||||
LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
|
LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
|
||||||
|
|
|
@ -8,7 +8,6 @@ type Fn = dyn FnOnce() -> u8;
|
||||||
const TEST: Fn = some_fn;
|
const TEST: Fn = some_fn;
|
||||||
//~^ ERROR cannot find value `some_fn` in this scope
|
//~^ ERROR cannot find value `some_fn` in this scope
|
||||||
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
||||||
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
|
||||||
const TEST2: (Fn, u8) = (TEST, 0);
|
const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
||||||
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
||||||
|
|
|
@ -13,16 +13,7 @@ LL | const TEST: Fn = some_fn;
|
||||||
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18
|
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:14
|
||||||
|
|
|
||||||
LL | const TEST: Fn = some_fn;
|
|
||||||
| ^^^^^^^ doesn't have a size known at compile-time
|
|
||||||
|
|
|
||||||
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
|
|
||||||
= note: constant expressions must have a statically known size
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
|
||||||
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14
|
|
||||||
|
|
|
|
||||||
LL | const TEST2: (Fn, u8) = (TEST, 0);
|
LL | const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -31,7 +22,7 @@ LL | const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
= note: only the last element of a tuple may have a dynamically sized type
|
= note: only the last element of a tuple may have a dynamically sized type
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25
|
--> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:25
|
||||||
|
|
|
|
||||||
LL | const TEST2: (Fn, u8) = (TEST, 0);
|
LL | const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -39,7 +30,7 @@ LL | const TEST2: (Fn, u8) = (TEST, 0);
|
||||||
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
|
= help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
|
||||||
= note: only the last element of a tuple may have a dynamically sized type
|
= note: only the last element of a tuple may have a dynamically sized type
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0425.
|
Some errors have detailed explanations: E0277, E0425.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -8,17 +8,6 @@ LL | impl const dyn T {
|
||||||
|
|
|
|
||||||
= note: only trait implementations may be annotated with `const`
|
= note: only trait implementations may be annotated with `const`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/span-bug-issue-121418.rs:8:27
|
|
||||||
|
|
|
||||||
LL | pub const fn new() -> std::sync::Mutex<dyn T> {}
|
|
||||||
| --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
|
|
||||||
| |
|
|
||||||
| implicitly returns `()` as its body has no tail or `return` expression
|
|
||||||
|
|
|
||||||
= note: expected struct `Mutex<(dyn T + 'static)>`
|
|
||||||
found unit type `()`
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
|
error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
|
||||||
--> $DIR/span-bug-issue-121418.rs:8:27
|
--> $DIR/span-bug-issue-121418.rs:8:27
|
||||||
|
|
|
|
||||||
|
@ -30,6 +19,17 @@ note: required because it appears within the type `Mutex<(dyn T + 'static)>`
|
||||||
--> $SRC_DIR/std/src/sync/poison/mutex.rs:LL:COL
|
--> $SRC_DIR/std/src/sync/poison/mutex.rs:LL:COL
|
||||||
= note: the return type of a function must have a statically known size
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/span-bug-issue-121418.rs:8:27
|
||||||
|
|
|
||||||
|
LL | pub const fn new() -> std::sync::Mutex<dyn T> {}
|
||||||
|
| --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
|
||||||
|
| |
|
||||||
|
| implicitly returns `()` as its body has no tail or `return` expression
|
||||||
|
|
|
||||||
|
= note: expected struct `Mutex<(dyn T + 'static)>`
|
||||||
|
found unit type `()`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0308.
|
Some errors have detailed explanations: E0277, E0308.
|
||||||
|
|
|
@ -22,7 +22,7 @@ note: method defined here
|
||||||
--> $DIR/issue-52893.rs:11:8
|
--> $DIR/issue-52893.rs:11:8
|
||||||
|
|
|
|
||||||
LL | fn push(self, other: T) -> Self::PushRes;
|
LL | fn push(self, other: T) -> Self::PushRes;
|
||||||
| ^^^^
|
| ^^^^ -----
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn weird0() -> impl Sized + !Sized {}
|
fn weird0() -> impl Sized + !Sized {}
|
||||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
//~^ ERROR type mismatch resolving
|
||||||
fn weird1() -> impl !Sized + Sized {}
|
fn weird1() -> impl !Sized + Sized {}
|
||||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
//~^ ERROR type mismatch resolving
|
||||||
fn weird2() -> impl !Sized {}
|
fn weird2() -> impl !Sized {}
|
||||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
//~^ ERROR type mismatch resolving
|
||||||
|
//~| ERROR the size for values of type
|
||||||
|
|
|
@ -1,20 +1,29 @@
|
||||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
|
||||||
|
|
|
||||||
LL | fn weird0() -> impl Sized + !Sized {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
|
||||||
|
|
|
||||||
LL | fn weird1() -> impl !Sized + Sized {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||||
|
|
|
|
||||||
LL | fn weird2() -> impl !Sized {}
|
LL | fn weird2() -> impl !Sized {}
|
||||||
| ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `impl !Sized`
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
||||||
|
|
|
||||||
|
LL | fn weird0() -> impl Sized + !Sized {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
||||||
|
|
|
||||||
|
LL | fn weird1() -> impl !Sized + Sized {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `impl !Sized == ()`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||||
|
|
|
||||||
|
LL | fn weird2() -> impl !Sized {}
|
||||||
|
| ^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
||||||
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
||||||
|
@ -30,6 +39,7 @@ note: required by a bound in `consume`
|
||||||
LL | fn consume(_: impl Trait) {}
|
LL | fn consume(_: impl Trait) {}
|
||||||
| ^^^^^ required by this bound in `consume`
|
| ^^^^^ required by this bound in `consume`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
Some errors have detailed explanations: E0271, E0277.
|
||||||
|
For more information about an error, try `rustc --explain E0271`.
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
#![feature(negative_bounds, unboxed_closures)]
|
#![feature(negative_bounds, unboxed_closures)]
|
||||||
|
|
||||||
fn produce() -> impl !Fn<(u32,)> {}
|
fn produce() -> impl !Fn<(u32,)> {}
|
||||||
//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
|
//~^ ERROR type mismatch resolving
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
|
error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
|
||||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
||||||
|
|
|
|
||||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||||
| ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
|
| ^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0271`.
|
||||||
|
|
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:17:19
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:17:19
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:20:19
|
||||||
|
|
|
||||||
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:20:19
|
||||||
|
|
|
||||||
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
#![cfg_attr(const_arg, feature(generic_const_exprs))]
|
||||||
|
#![expect(incomplete_features)]
|
||||||
|
|
||||||
|
//@ revisions: default const_arg
|
||||||
|
|
||||||
|
//@[const_arg] check-pass
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
const START: u32;
|
||||||
|
const END: u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||||
|
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||||
|
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||||
|
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,10 +1,14 @@
|
||||||
|
//@known-bug: #127972
|
||||||
|
//@ failure-status: 101
|
||||||
|
//@ normalize-stderr: "note: .*\n\n" -> ""
|
||||||
|
//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
|
||||||
|
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||||
|
//@ rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
||||||
#![feature(pattern_types, pattern_type_macro)]
|
#![feature(pattern_types, pattern_type_macro)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
type Pat<const START: u32, const END: u32> =
|
type Pat<const START: u32, const END: u32> =
|
||||||
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
|
||||||
//~| ERROR generic arguments are not allowed on const parameter `END`
|
|
||||||
//~| ERROR associated item constraints are not allowed here
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,38 +1,14 @@
|
||||||
error[E0109]: type and const arguments are not allowed on const parameter `START`
|
error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:44
|
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
|
||||||
|
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
| ----- ^^ ^^^ ^ type and const arguments not allowed
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
|
||||||
| not allowed on const parameter `START`
|
|
||||||
|
|
|
||||||
note: const parameter `START` defined here
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:16
|
|
||||||
|
|
|
||||||
LL | type Pat<const START: u32, const END: u32> =
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error[E0109]: generic arguments are not allowed on const parameter `END`
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
|
|
||||||
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
|
||||||
| --- ^ generic argument not allowed
|
|
||||||
| |
|
|
||||||
| not allowed on const parameter `END`
|
|
||||||
|
|
|
||||||
note: const parameter `END` defined here
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:34
|
|
||||||
|
|
|
||||||
LL | type Pat<const START: u32, const END: u32> =
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error[E0229]: associated item constraints are not allowed here
|
Box<dyn Any>
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
|
query stack during panic:
|
||||||
|
|
#0 [type_of] expanding type alias `Pat`
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
#1 [check_well_formed] checking that `Pat` is well-formed
|
||||||
| ^^^^^^^^^^ associated item constraint not allowed here
|
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0109, E0229.
|
|
||||||
For more information about an error, try `rustc --explain E0109`.
|
|
||||||
|
|
|
@ -8,6 +8,6 @@ type NonNullU32_2 = pattern_type!(u32 is 1..=);
|
||||||
type Positive2 = pattern_type!(i32 is 0..=);
|
type Positive2 = pattern_type!(i32 is 0..=);
|
||||||
//~^ ERROR: inclusive range with no end
|
//~^ ERROR: inclusive range with no end
|
||||||
type Wild = pattern_type!(() is _);
|
type Wild = pattern_type!(() is _);
|
||||||
//~^ ERROR: wildcard patterns are not permitted for pattern types
|
//~^ ERROR: pattern not supported in pattern types
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -24,7 +24,7 @@ LL - type Positive2 = pattern_type!(i32 is 0..=);
|
||||||
LL + type Positive2 = pattern_type!(i32 is 0..);
|
LL + type Positive2 = pattern_type!(i32 is 0..);
|
||||||
|
|
|
|
||||||
|
|
||||||
error: wildcard patterns are not permitted for pattern types
|
error: pattern not supported in pattern types
|
||||||
--> $DIR/bad_pat.rs:10:33
|
--> $DIR/bad_pat.rs:10:33
|
||||||
|
|
|
|
||||||
LL | type Wild = pattern_type!(() is _);
|
LL | type Wild = pattern_type!(() is _);
|
||||||
|
|
10
tests/ui/type/pattern_types/const_block.rs
Normal file
10
tests/ui/type/pattern_types/const_block.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
//~^ ERROR: cycle
|
||||||
|
|
||||||
|
fn main() {}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue