Auto merge of #104310 - Dylan-DPC:rollup-wgt1z4a, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #102049 (Add the `#[derive_const]` attribute) - #103970 (Unhide unknown spans) - #104206 (Remove `save_and_restore_in_snapshot_flag`, use `ObligationCtxt` more) - #104214 (Emit error in `collecting_trait_impl_trait_tys` on mismatched signatures) - #104267 (rustdoc: use checkbox instead of switch for settings toggles) - #104302 (Update cargo) - #104303 (UI tests can be assigned to T-compiler) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5f4e73c4a4
64 changed files with 787 additions and 467 deletions
|
@ -273,7 +273,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo"
|
name = "cargo"
|
||||||
version = "0.67.0"
|
version = "0.68.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"atty",
|
"atty",
|
||||||
|
|
|
@ -34,6 +34,7 @@ impl MultiItemModifier for Expander {
|
||||||
span: Span,
|
span: Span,
|
||||||
meta_item: &ast::MetaItem,
|
meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
_is_derive_const: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
|
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
|
||||||
let attr = &ecx.attribute(meta_item.clone());
|
let attr = &ecx.attribute(meta_item.clone());
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_session::Session;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
pub(crate) struct Expander;
|
pub(crate) struct Expander(pub bool);
|
||||||
|
|
||||||
impl MultiItemModifier for Expander {
|
impl MultiItemModifier for Expander {
|
||||||
fn expand(
|
fn expand(
|
||||||
|
@ -19,6 +19,7 @@ impl MultiItemModifier for Expander {
|
||||||
span: Span,
|
span: Span,
|
||||||
meta_item: &ast::MetaItem,
|
meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
_: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
let sess = ecx.sess;
|
let sess = ecx.sess;
|
||||||
if report_bad_target(sess, &item, span) {
|
if report_bad_target(sess, &item, span) {
|
||||||
|
@ -58,20 +59,20 @@ impl MultiItemModifier for Expander {
|
||||||
report_path_args(sess, &meta);
|
report_path_args(sess, &meta);
|
||||||
meta.path
|
meta.path
|
||||||
})
|
})
|
||||||
.map(|path| (path, dummy_annotatable(), None))
|
.map(|path| (path, dummy_annotatable(), None, self.0))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Do not configure or clone items unless necessary.
|
// Do not configure or clone items unless necessary.
|
||||||
match &mut resolutions[..] {
|
match &mut resolutions[..] {
|
||||||
[] => {}
|
[] => {}
|
||||||
[(_, first_item, _), others @ ..] => {
|
[(_, first_item, ..), others @ ..] => {
|
||||||
*first_item = cfg_eval(
|
*first_item = cfg_eval(
|
||||||
sess,
|
sess,
|
||||||
features,
|
features,
|
||||||
item.clone(),
|
item.clone(),
|
||||||
ecx.current_expansion.lint_node_id,
|
ecx.current_expansion.lint_node_id,
|
||||||
);
|
);
|
||||||
for (_, item, _) in others {
|
for (_, item, _, _) in others {
|
||||||
*item = first_item.clone();
|
*item = first_item.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub fn expand_deriving_copy(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
|
@ -22,6 +23,7 @@ pub fn expand_deriving_copy(
|
||||||
supports_unions: true,
|
supports_unions: true,
|
||||||
methods: Vec::new(),
|
methods: Vec::new(),
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push);
|
trait_def.expand(cx, mitem, item, push);
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub fn expand_deriving_clone(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
// The simple form is `fn clone(&self) -> Self { *self }`, possibly with
|
// The simple form is `fn clone(&self) -> Self { *self }`, possibly with
|
||||||
// some additional `AssertParamIsClone` assertions.
|
// some additional `AssertParamIsClone` assertions.
|
||||||
|
@ -87,6 +88,7 @@ pub fn expand_deriving_clone(
|
||||||
combine_substructure: substructure,
|
combine_substructure: substructure,
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
trait_def.expand_ext(cx, mitem, item, push, is_simple)
|
trait_def.expand_ext(cx, mitem, item, push, is_simple)
|
||||||
|
|
|
@ -15,6 +15,7 @@ pub fn expand_deriving_eq(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let span = cx.with_def_site_ctxt(span);
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let inline = cx.meta_word(span, sym::inline);
|
let inline = cx.meta_word(span, sym::inline);
|
||||||
|
@ -42,6 +43,7 @@ pub fn expand_deriving_eq(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
|
super::inject_impl_of_structural_trait(cx, span, item, path_std!(marker::StructuralEq), push);
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_ord(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let inline = cx.meta_word(span, sym::inline);
|
let inline = cx.meta_word(span, sym::inline);
|
||||||
let attrs = thin_vec![cx.attribute(inline)];
|
let attrs = thin_vec![cx.attribute(inline)];
|
||||||
|
@ -34,6 +35,7 @@ pub fn expand_deriving_ord(
|
||||||
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
|
combine_substructure: combine_substructure(Box::new(|a, b, c| cs_cmp(a, b, c))),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub fn expand_deriving_partial_eq(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
|
fn cs_eq(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> BlockOrExpr {
|
||||||
let base = true;
|
let base = true;
|
||||||
|
@ -89,6 +90,7 @@ pub fn expand_deriving_partial_eq(
|
||||||
supports_unions: false,
|
supports_unions: false,
|
||||||
methods,
|
methods,
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_partial_ord(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let ordering_ty = Path(path_std!(cmp::Ordering));
|
let ordering_ty = Path(path_std!(cmp::Ordering));
|
||||||
let ret_ty =
|
let ret_ty =
|
||||||
|
@ -43,6 +44,7 @@ pub fn expand_deriving_partial_ord(
|
||||||
supports_unions: false,
|
supports_unions: false,
|
||||||
methods: vec![partial_cmp_def],
|
methods: vec![partial_cmp_def],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_debug(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
// &mut ::std::fmt::Formatter
|
// &mut ::std::fmt::Formatter
|
||||||
let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut);
|
let fmtr = Ref(Box::new(Path(path_std!(fmt::Formatter))), ast::Mutability::Mut);
|
||||||
|
@ -37,6 +38,7 @@ pub fn expand_deriving_debug(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let krate = sym::rustc_serialize;
|
let krate = sym::rustc_serialize;
|
||||||
let typaram = sym::__D;
|
let typaram = sym::__D;
|
||||||
|
@ -55,6 +56,7 @@ pub fn expand_deriving_rustc_decodable(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub fn expand_deriving_default(
|
||||||
mitem: &ast::MetaItem,
|
mitem: &ast::MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
|
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ pub fn expand_deriving_default(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let krate = sym::rustc_serialize;
|
let krate = sym::rustc_serialize;
|
||||||
let typaram = sym::__S;
|
let typaram = sym::__S;
|
||||||
|
@ -139,6 +140,7 @@ pub fn expand_deriving_rustc_encodable(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
trait_def.expand(cx, mitem, item, push)
|
trait_def.expand(cx, mitem, item, push)
|
||||||
|
|
|
@ -171,7 +171,7 @@ use rustc_ast::{GenericArg, GenericParamKind, VariantData};
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::Not;
|
use std::ops::Not;
|
||||||
|
@ -204,6 +204,8 @@ pub struct TraitDef<'a> {
|
||||||
pub methods: Vec<MethodDef<'a>>,
|
pub methods: Vec<MethodDef<'a>>,
|
||||||
|
|
||||||
pub associated_types: Vec<(Ident, Ty)>,
|
pub associated_types: Vec<(Ident, Ty)>,
|
||||||
|
|
||||||
|
pub is_const: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MethodDef<'a> {
|
pub struct MethodDef<'a> {
|
||||||
|
@ -730,7 +732,7 @@ impl<'a> TraitDef<'a> {
|
||||||
unsafety: ast::Unsafe::No,
|
unsafety: ast::Unsafe::No,
|
||||||
polarity: ast::ImplPolarity::Positive,
|
polarity: ast::ImplPolarity::Positive,
|
||||||
defaultness: ast::Defaultness::Final,
|
defaultness: ast::Defaultness::Final,
|
||||||
constness: ast::Const::No,
|
constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No },
|
||||||
generics: trait_generics,
|
generics: trait_generics,
|
||||||
of_trait: opt_trait_ref,
|
of_trait: opt_trait_ref,
|
||||||
self_ty: self_type,
|
self_ty: self_type,
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub fn expand_deriving_hash(
|
||||||
mitem: &MetaItem,
|
mitem: &MetaItem,
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
|
is_const: bool,
|
||||||
) {
|
) {
|
||||||
let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std);
|
let path = Path::new_(pathvec_std!(hash::Hash), vec![], PathKind::Std);
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ pub fn expand_deriving_hash(
|
||||||
})),
|
})),
|
||||||
}],
|
}],
|
||||||
associated_types: Vec::new(),
|
associated_types: Vec::new(),
|
||||||
|
is_const,
|
||||||
};
|
};
|
||||||
|
|
||||||
hash_trait_def.expand(cx, mitem, item, push);
|
hash_trait_def.expand(cx, mitem, item, push);
|
||||||
|
|
|
@ -38,9 +38,10 @@ pub mod partial_ord;
|
||||||
|
|
||||||
pub mod generic;
|
pub mod generic;
|
||||||
|
|
||||||
pub(crate) struct BuiltinDerive(
|
pub(crate) type BuiltinDeriveFn =
|
||||||
pub(crate) fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)),
|
fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable), bool);
|
||||||
);
|
|
||||||
|
pub(crate) struct BuiltinDerive(pub(crate) BuiltinDeriveFn);
|
||||||
|
|
||||||
impl MultiItemModifier for BuiltinDerive {
|
impl MultiItemModifier for BuiltinDerive {
|
||||||
fn expand(
|
fn expand(
|
||||||
|
@ -49,6 +50,7 @@ impl MultiItemModifier for BuiltinDerive {
|
||||||
span: Span,
|
span: Span,
|
||||||
meta_item: &MetaItem,
|
meta_item: &MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
is_derive_const: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
// FIXME: Built-in derives often forget to give spans contexts,
|
// FIXME: Built-in derives often forget to give spans contexts,
|
||||||
// so we are doing it here in a centralized way.
|
// so we are doing it here in a centralized way.
|
||||||
|
@ -57,7 +59,12 @@ impl MultiItemModifier for BuiltinDerive {
|
||||||
match item {
|
match item {
|
||||||
Annotatable::Stmt(stmt) => {
|
Annotatable::Stmt(stmt) => {
|
||||||
if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
|
if let ast::StmtKind::Item(item) = stmt.into_inner().kind {
|
||||||
(self.0)(ecx, span, meta_item, &Annotatable::Item(item), &mut |a| {
|
(self.0)(
|
||||||
|
ecx,
|
||||||
|
span,
|
||||||
|
meta_item,
|
||||||
|
&Annotatable::Item(item),
|
||||||
|
&mut |a| {
|
||||||
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
|
// Cannot use 'ecx.stmt_item' here, because we need to pass 'ecx'
|
||||||
// to the function
|
// to the function
|
||||||
items.push(Annotatable::Stmt(P(ast::Stmt {
|
items.push(Annotatable::Stmt(P(ast::Stmt {
|
||||||
|
@ -65,13 +72,15 @@ impl MultiItemModifier for BuiltinDerive {
|
||||||
kind: ast::StmtKind::Item(a.expect_item()),
|
kind: ast::StmtKind::Item(a.expect_item()),
|
||||||
span,
|
span,
|
||||||
})));
|
})));
|
||||||
});
|
},
|
||||||
|
is_derive_const,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
unreachable!("should have already errored on non-item statement")
|
unreachable!("should have already errored on non-item statement")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
|
(self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a), is_derive_const);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExpandResult::Ready(items)
|
ExpandResult::Ready(items)
|
||||||
|
|
|
@ -99,7 +99,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||||
bench: test::expand_bench,
|
bench: test::expand_bench,
|
||||||
cfg_accessible: cfg_accessible::Expander,
|
cfg_accessible: cfg_accessible::Expander,
|
||||||
cfg_eval: cfg_eval::expand,
|
cfg_eval: cfg_eval::expand,
|
||||||
derive: derive::Expander,
|
derive: derive::Expander(false),
|
||||||
|
derive_const: derive::Expander(true),
|
||||||
global_allocator: global_allocator::expand,
|
global_allocator: global_allocator::expand,
|
||||||
test: test::expand_test,
|
test: test::expand_test,
|
||||||
test_case: test::expand_test_case,
|
test_case: test::expand_test_case,
|
||||||
|
|
|
@ -47,7 +47,10 @@ passes_no_coverage_not_coverable =
|
||||||
|
|
||||||
passes_should_be_applied_to_fn =
|
passes_should_be_applied_to_fn =
|
||||||
attribute should be applied to a function definition
|
attribute should be applied to a function definition
|
||||||
.label = not a function definition
|
.label = {$on_crate ->
|
||||||
|
[true] cannot be applied to crates
|
||||||
|
*[false] not a function definition
|
||||||
|
}
|
||||||
|
|
||||||
passes_naked_tracked_caller =
|
passes_naked_tracked_caller =
|
||||||
cannot use `#[track_caller]` with `#[naked]`
|
cannot use `#[track_caller]` with `#[naked]`
|
||||||
|
|
|
@ -52,7 +52,6 @@ impl Emitter for AnnotateSnippetEmitterWriter {
|
||||||
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
|
let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args);
|
||||||
|
|
||||||
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||||
&self.source_map,
|
|
||||||
&mut primary_span,
|
&mut primary_span,
|
||||||
&mut children,
|
&mut children,
|
||||||
&diag.level,
|
&diag.level,
|
||||||
|
|
|
@ -314,7 +314,6 @@ pub trait Emitter: Translate {
|
||||||
|
|
||||||
fn fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
fn fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||||
&self,
|
&self,
|
||||||
source_map: &Option<Lrc<SourceMap>>,
|
|
||||||
span: &mut MultiSpan,
|
span: &mut MultiSpan,
|
||||||
children: &mut Vec<SubDiagnostic>,
|
children: &mut Vec<SubDiagnostic>,
|
||||||
level: &Level,
|
level: &Level,
|
||||||
|
@ -340,7 +339,7 @@ pub trait Emitter: Translate {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !backtrace {
|
if !backtrace {
|
||||||
self.fix_multispans_in_extern_macros(source_map, span, children);
|
self.fix_multispans_in_extern_macros(span, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_multispans_macro_backtrace(span, children, backtrace);
|
self.render_multispans_macro_backtrace(span, children, backtrace);
|
||||||
|
@ -480,15 +479,13 @@ pub trait Emitter: Translate {
|
||||||
// this will change the span to point at the use site.
|
// this will change the span to point at the use site.
|
||||||
fn fix_multispans_in_extern_macros(
|
fn fix_multispans_in_extern_macros(
|
||||||
&self,
|
&self,
|
||||||
source_map: &Option<Lrc<SourceMap>>,
|
|
||||||
span: &mut MultiSpan,
|
span: &mut MultiSpan,
|
||||||
children: &mut Vec<SubDiagnostic>,
|
children: &mut Vec<SubDiagnostic>,
|
||||||
) {
|
) {
|
||||||
let Some(source_map) = source_map else { return };
|
|
||||||
debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children);
|
debug!("fix_multispans_in_extern_macros: before: span={:?} children={:?}", span, children);
|
||||||
self.fix_multispan_in_extern_macros(source_map, span);
|
self.fix_multispan_in_extern_macros(span);
|
||||||
for child in children.iter_mut() {
|
for child in children.iter_mut() {
|
||||||
self.fix_multispan_in_extern_macros(source_map, &mut child.span);
|
self.fix_multispan_in_extern_macros(&mut child.span);
|
||||||
}
|
}
|
||||||
debug!("fix_multispans_in_extern_macros: after: span={:?} children={:?}", span, children);
|
debug!("fix_multispans_in_extern_macros: after: span={:?} children={:?}", span, children);
|
||||||
}
|
}
|
||||||
|
@ -496,7 +493,8 @@ pub trait Emitter: Translate {
|
||||||
// This "fixes" MultiSpans that contain `Span`s pointing to locations inside of external macros.
|
// This "fixes" MultiSpans that contain `Span`s pointing to locations inside of external macros.
|
||||||
// Since these locations are often difficult to read,
|
// Since these locations are often difficult to read,
|
||||||
// we move these spans from the external macros to their corresponding use site.
|
// we move these spans from the external macros to their corresponding use site.
|
||||||
fn fix_multispan_in_extern_macros(&self, source_map: &Lrc<SourceMap>, span: &mut MultiSpan) {
|
fn fix_multispan_in_extern_macros(&self, span: &mut MultiSpan) {
|
||||||
|
let Some(source_map) = self.source_map() else { return };
|
||||||
// First, find all the spans in external macros and point instead at their use site.
|
// First, find all the spans in external macros and point instead at their use site.
|
||||||
let replacements: Vec<(Span, Span)> = span
|
let replacements: Vec<(Span, Span)> = span
|
||||||
.primary_spans()
|
.primary_spans()
|
||||||
|
@ -544,7 +542,6 @@ impl Emitter for EmitterWriter {
|
||||||
debug!("emit_diagnostic: suggestions={:?}", suggestions);
|
debug!("emit_diagnostic: suggestions={:?}", suggestions);
|
||||||
|
|
||||||
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
|
||||||
&self.sm,
|
|
||||||
&mut primary_span,
|
&mut primary_span,
|
||||||
&mut children,
|
&mut children,
|
||||||
&diag.level,
|
&diag.level,
|
||||||
|
@ -2213,12 +2210,9 @@ impl FileWithAnnotatedLines {
|
||||||
|
|
||||||
if let Some(ref sm) = emitter.source_map() {
|
if let Some(ref sm) = emitter.source_map() {
|
||||||
for span_label in msp.span_labels() {
|
for span_label in msp.span_labels() {
|
||||||
if span_label.span.is_dummy() {
|
let fixup_lo_hi = |span: Span| {
|
||||||
continue;
|
let lo = sm.lookup_char_pos(span.lo());
|
||||||
}
|
let mut hi = sm.lookup_char_pos(span.hi());
|
||||||
|
|
||||||
let lo = sm.lookup_char_pos(span_label.span.lo());
|
|
||||||
let mut hi = sm.lookup_char_pos(span_label.span.hi());
|
|
||||||
|
|
||||||
// Watch out for "empty spans". If we get a span like 6..6, we
|
// Watch out for "empty spans". If we get a span like 6..6, we
|
||||||
// want to just display a `^` at 6, so convert that to
|
// want to just display a `^` at 6, so convert that to
|
||||||
|
@ -2229,6 +2223,32 @@ impl FileWithAnnotatedLines {
|
||||||
if lo.col_display == hi.col_display && lo.line == hi.line {
|
if lo.col_display == hi.col_display && lo.line == hi.line {
|
||||||
hi.col_display += 1;
|
hi.col_display += 1;
|
||||||
}
|
}
|
||||||
|
(lo, hi)
|
||||||
|
};
|
||||||
|
|
||||||
|
if span_label.span.is_dummy() {
|
||||||
|
if let Some(span) = msp.primary_span() {
|
||||||
|
// if we don't know where to render the annotation, emit it as a note
|
||||||
|
// on the primary span.
|
||||||
|
|
||||||
|
let (lo, hi) = fixup_lo_hi(span);
|
||||||
|
|
||||||
|
let ann = Annotation {
|
||||||
|
start_col: lo.col_display,
|
||||||
|
end_col: hi.col_display,
|
||||||
|
is_primary: span_label.is_primary,
|
||||||
|
label: span_label
|
||||||
|
.label
|
||||||
|
.as_ref()
|
||||||
|
.map(|m| emitter.translate_message(m, args).to_string()),
|
||||||
|
annotation_type: AnnotationType::Singleline,
|
||||||
|
};
|
||||||
|
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (lo, hi) = fixup_lo_hi(span_label.span);
|
||||||
|
|
||||||
if lo.line != hi.line {
|
if lo.line != hi.line {
|
||||||
let ml = MultilineAnnotation {
|
let ml = MultilineAnnotation {
|
||||||
|
|
|
@ -250,6 +250,7 @@ pub trait MultiItemModifier {
|
||||||
span: Span,
|
span: Span,
|
||||||
meta_item: &ast::MetaItem,
|
meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
is_derive_const: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable>;
|
) -> ExpandResult<Vec<Annotatable>, Annotatable>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +264,7 @@ where
|
||||||
span: Span,
|
span: Span,
|
||||||
meta_item: &ast::MetaItem,
|
meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
_is_derive_const: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
ExpandResult::Ready(self(ecx, span, meta_item, item))
|
ExpandResult::Ready(self(ecx, span, meta_item, item))
|
||||||
}
|
}
|
||||||
|
@ -873,7 +875,7 @@ impl SyntaxExtension {
|
||||||
/// Error type that denotes indeterminacy.
|
/// Error type that denotes indeterminacy.
|
||||||
pub struct Indeterminate;
|
pub struct Indeterminate;
|
||||||
|
|
||||||
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>)>;
|
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>, bool)>;
|
||||||
|
|
||||||
pub trait ResolverExpand {
|
pub trait ResolverExpand {
|
||||||
fn next_node_id(&mut self) -> NodeId;
|
fn next_node_id(&mut self) -> NodeId;
|
||||||
|
|
|
@ -337,6 +337,7 @@ pub enum InvocationKind {
|
||||||
},
|
},
|
||||||
Derive {
|
Derive {
|
||||||
path: ast::Path,
|
path: ast::Path,
|
||||||
|
is_const: bool,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -478,13 +479,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
derive_invocations.reserve(derives.len());
|
derive_invocations.reserve(derives.len());
|
||||||
derives
|
derives
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, item, _exts)| {
|
.map(|(path, item, _exts, is_const)| {
|
||||||
// FIXME: Consider using the derive resolutions (`_exts`)
|
// FIXME: Consider using the derive resolutions (`_exts`)
|
||||||
// instead of enqueuing the derives to be resolved again later.
|
// instead of enqueuing the derives to be resolved again later.
|
||||||
let expn_id = LocalExpnId::fresh_empty();
|
let expn_id = LocalExpnId::fresh_empty();
|
||||||
derive_invocations.push((
|
derive_invocations.push((
|
||||||
Invocation {
|
Invocation {
|
||||||
kind: InvocationKind::Derive { path, item },
|
kind: InvocationKind::Derive { path, item, is_const },
|
||||||
fragment_kind,
|
fragment_kind,
|
||||||
expansion_data: ExpansionData {
|
expansion_data: ExpansionData {
|
||||||
id: expn_id,
|
id: expn_id,
|
||||||
|
@ -717,7 +718,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
SyntaxExtensionKind::LegacyAttr(expander) => {
|
SyntaxExtensionKind::LegacyAttr(expander) => {
|
||||||
match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
|
match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
|
||||||
Ok(meta) => {
|
Ok(meta) => {
|
||||||
let items = match expander.expand(self.cx, span, &meta, item) {
|
let items = match expander.expand(self.cx, span, &meta, item, false) {
|
||||||
ExpandResult::Ready(items) => items,
|
ExpandResult::Ready(items) => items,
|
||||||
ExpandResult::Retry(item) => {
|
ExpandResult::Retry(item) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
|
@ -749,19 +750,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
InvocationKind::Derive { path, item } => match ext {
|
InvocationKind::Derive { path, item, is_const } => match ext {
|
||||||
SyntaxExtensionKind::Derive(expander)
|
SyntaxExtensionKind::Derive(expander)
|
||||||
| SyntaxExtensionKind::LegacyDerive(expander) => {
|
| SyntaxExtensionKind::LegacyDerive(expander) => {
|
||||||
if let SyntaxExtensionKind::Derive(..) = ext {
|
if let SyntaxExtensionKind::Derive(..) = ext {
|
||||||
self.gate_proc_macro_input(&item);
|
self.gate_proc_macro_input(&item);
|
||||||
}
|
}
|
||||||
let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path };
|
let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path };
|
||||||
let items = match expander.expand(self.cx, span, &meta, item) {
|
let items = match expander.expand(self.cx, span, &meta, item, is_const) {
|
||||||
ExpandResult::Ready(items) => items,
|
ExpandResult::Ready(items) => items,
|
||||||
ExpandResult::Retry(item) => {
|
ExpandResult::Retry(item) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
return ExpandResult::Retry(Invocation {
|
return ExpandResult::Retry(Invocation {
|
||||||
kind: InvocationKind::Derive { path: meta.path, item },
|
kind: InvocationKind::Derive { path: meta.path, item, is_const },
|
||||||
..invoc
|
..invoc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ impl MultiItemModifier for DeriveProcMacro {
|
||||||
span: Span,
|
span: Span,
|
||||||
_meta_item: &ast::MetaItem,
|
_meta_item: &ast::MetaItem,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
|
_is_derive_const: bool,
|
||||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||||
// We need special handling for statement items
|
// We need special handling for statement items
|
||||||
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
|
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
|
||||||
|
|
|
@ -9,14 +9,15 @@ use rustc_hir::intravisit;
|
||||||
use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
|
use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
|
||||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{self, TyCtxtInferExt};
|
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||||
use rustc_infer::traits::util;
|
use rustc_infer::traits::util;
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::util::ExplicitSelf;
|
use rustc_middle::ty::util::ExplicitSelf;
|
||||||
use rustc_middle::ty::InternalSubsts;
|
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, AssocItem, DefIdTree, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
self, AssocItem, DefIdTree, TraitRef, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||||
|
TypeVisitable,
|
||||||
};
|
};
|
||||||
|
use rustc_middle::ty::{FnSig, InternalSubsts};
|
||||||
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||||
|
@ -303,102 +304,19 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(terr) = result {
|
if let Err(terr) = result {
|
||||||
debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
|
debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
|
||||||
|
|
||||||
let (impl_err_span, trait_err_span) =
|
let emitted = report_trait_method_mismatch(
|
||||||
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
|
tcx,
|
||||||
|
&mut cause,
|
||||||
cause.span = impl_err_span;
|
&infcx,
|
||||||
|
|
||||||
let mut diag = struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
cause.span(),
|
|
||||||
E0053,
|
|
||||||
"method `{}` has an incompatible type for trait",
|
|
||||||
trait_m.name
|
|
||||||
);
|
|
||||||
match &terr {
|
|
||||||
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
|
|
||||||
if trait_m.fn_has_self_parameter =>
|
|
||||||
{
|
|
||||||
let ty = trait_sig.inputs()[0];
|
|
||||||
let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
|
|
||||||
ExplicitSelf::ByValue => "self".to_owned(),
|
|
||||||
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
|
||||||
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
|
|
||||||
_ => format!("self: {ty}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
|
|
||||||
// span points only at the type `Box<Self`>, but we want to cover the whole
|
|
||||||
// argument pattern and type.
|
|
||||||
let span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
|
|
||||||
ImplItemKind::Fn(ref sig, body) => tcx
|
|
||||||
.hir()
|
|
||||||
.body_param_names(body)
|
|
||||||
.zip(sig.decl.inputs.iter())
|
|
||||||
.map(|(param, ty)| param.span.to(ty.span))
|
|
||||||
.next()
|
|
||||||
.unwrap_or(impl_err_span),
|
|
||||||
_ => bug!("{:?} is not a method", impl_m),
|
|
||||||
};
|
|
||||||
|
|
||||||
diag.span_suggestion(
|
|
||||||
span,
|
|
||||||
"change the self-receiver type to match the trait",
|
|
||||||
sugg,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(_, i) => {
|
|
||||||
if trait_sig.inputs().len() == *i {
|
|
||||||
// Suggestion to change output type. We do not suggest in `async` functions
|
|
||||||
// to avoid complex logic or incorrect output.
|
|
||||||
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
|
|
||||||
ImplItemKind::Fn(ref sig, _)
|
|
||||||
if sig.header.asyncness == hir::IsAsync::NotAsync =>
|
|
||||||
{
|
|
||||||
let msg = "change the output type to match the trait";
|
|
||||||
let ap = Applicability::MachineApplicable;
|
|
||||||
match sig.decl.output {
|
|
||||||
hir::FnRetTy::DefaultReturn(sp) => {
|
|
||||||
let sugg = format!("-> {} ", trait_sig.output());
|
|
||||||
diag.span_suggestion_verbose(sp, msg, sugg, ap);
|
|
||||||
}
|
|
||||||
hir::FnRetTy::Return(hir_ty) => {
|
|
||||||
let sugg = trait_sig.output();
|
|
||||||
diag.span_suggestion(hir_ty.span, msg, sugg, ap);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
} else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
|
|
||||||
diag.span_suggestion(
|
|
||||||
impl_err_span,
|
|
||||||
"change the parameter type to match the trait",
|
|
||||||
trait_ty,
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
infcx.err_ctxt().note_type_err(
|
|
||||||
&mut diag,
|
|
||||||
&cause,
|
|
||||||
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
|
|
||||||
Some(infer::ValuePairs::Terms(ExpectedFound {
|
|
||||||
expected: trait_fty.into(),
|
|
||||||
found: impl_fty.into(),
|
|
||||||
})),
|
|
||||||
terr,
|
terr,
|
||||||
false,
|
(trait_m, trait_fty),
|
||||||
false,
|
(impl_m, impl_fty),
|
||||||
|
&trait_sig,
|
||||||
|
&impl_trait_ref,
|
||||||
);
|
);
|
||||||
|
return Err(emitted);
|
||||||
return Err(diag.emit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all obligations are satisfied by the implementation's
|
// Check that all obligations are satisfied by the implementation's
|
||||||
|
@ -424,6 +342,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(tcx), level = "debug", ret)]
|
||||||
pub fn collect_trait_impl_trait_tys<'tcx>(
|
pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
|
@ -437,7 +356,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
|
|
||||||
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
|
||||||
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span();
|
||||||
let cause = ObligationCause::new(
|
let mut cause = ObligationCause::new(
|
||||||
return_span,
|
return_span,
|
||||||
impl_m_hir_id,
|
impl_m_hir_id,
|
||||||
ObligationCauseCode::CompareImplItemObligation {
|
ObligationCauseCode::CompareImplItemObligation {
|
||||||
|
@ -514,23 +433,35 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(?trait_sig, ?impl_sig, "equating function signatures");
|
||||||
|
|
||||||
|
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
|
||||||
|
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
|
||||||
|
|
||||||
// Unify the whole function signature. We need to do this to fully infer
|
// Unify the whole function signature. We need to do this to fully infer
|
||||||
// the lifetimes of the return type, but do this after unifying just the
|
// the lifetimes of the return type, but do this after unifying just the
|
||||||
// return types, since we want to avoid duplicating errors from
|
// return types, since we want to avoid duplicating errors from
|
||||||
// `compare_predicate_entailment`.
|
// `compare_predicate_entailment`.
|
||||||
match infcx
|
match infcx.at(&cause, param_env).eq(trait_fty, impl_fty) {
|
||||||
.at(&cause, param_env)
|
|
||||||
.eq(tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig)), tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig)))
|
|
||||||
{
|
|
||||||
Ok(infer::InferOk { value: (), obligations }) => {
|
Ok(infer::InferOk { value: (), obligations }) => {
|
||||||
ocx.register_obligations(obligations);
|
ocx.register_obligations(obligations);
|
||||||
}
|
}
|
||||||
Err(terr) => {
|
Err(terr) => {
|
||||||
let guar = tcx.sess.delay_span_bug(
|
// This function gets called during `compare_predicate_entailment` when normalizing a
|
||||||
return_span,
|
// signature that contains RPITIT. When the method signatures don't match, we have to
|
||||||
format!("could not unify `{trait_sig}` and `{impl_sig}`: {terr:?}"),
|
// emit an error now because `compare_predicate_entailment` will not report the error
|
||||||
|
// when normalization fails.
|
||||||
|
let emitted = report_trait_method_mismatch(
|
||||||
|
tcx,
|
||||||
|
&mut cause,
|
||||||
|
infcx,
|
||||||
|
terr,
|
||||||
|
(trait_m, trait_fty),
|
||||||
|
(impl_m, impl_fty),
|
||||||
|
&trait_sig,
|
||||||
|
&impl_trait_ref,
|
||||||
);
|
);
|
||||||
return Err(guar);
|
return Err(emitted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,6 +621,112 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_trait_method_mismatch<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
cause: &mut ObligationCause<'tcx>,
|
||||||
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
terr: TypeError<'tcx>,
|
||||||
|
(trait_m, trait_fty): (&AssocItem, Ty<'tcx>),
|
||||||
|
(impl_m, impl_fty): (&AssocItem, Ty<'tcx>),
|
||||||
|
trait_sig: &FnSig<'tcx>,
|
||||||
|
impl_trait_ref: &TraitRef<'tcx>,
|
||||||
|
) -> ErrorGuaranteed {
|
||||||
|
let (impl_err_span, trait_err_span) =
|
||||||
|
extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m);
|
||||||
|
|
||||||
|
cause.span = impl_err_span;
|
||||||
|
|
||||||
|
let mut diag = struct_span_err!(
|
||||||
|
tcx.sess,
|
||||||
|
cause.span(),
|
||||||
|
E0053,
|
||||||
|
"method `{}` has an incompatible type for trait",
|
||||||
|
trait_m.name
|
||||||
|
);
|
||||||
|
match &terr {
|
||||||
|
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
|
||||||
|
if trait_m.fn_has_self_parameter =>
|
||||||
|
{
|
||||||
|
let ty = trait_sig.inputs()[0];
|
||||||
|
let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
|
||||||
|
ExplicitSelf::ByValue => "self".to_owned(),
|
||||||
|
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
||||||
|
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
|
||||||
|
_ => format!("self: {ty}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
|
||||||
|
// span points only at the type `Box<Self`>, but we want to cover the whole
|
||||||
|
// argument pattern and type.
|
||||||
|
let span = match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
|
||||||
|
ImplItemKind::Fn(ref sig, body) => tcx
|
||||||
|
.hir()
|
||||||
|
.body_param_names(body)
|
||||||
|
.zip(sig.decl.inputs.iter())
|
||||||
|
.map(|(param, ty)| param.span.to(ty.span))
|
||||||
|
.next()
|
||||||
|
.unwrap_or(impl_err_span),
|
||||||
|
_ => bug!("{:?} is not a method", impl_m),
|
||||||
|
};
|
||||||
|
|
||||||
|
diag.span_suggestion(
|
||||||
|
span,
|
||||||
|
"change the self-receiver type to match the trait",
|
||||||
|
sugg,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(_, i) => {
|
||||||
|
if trait_sig.inputs().len() == *i {
|
||||||
|
// Suggestion to change output type. We do not suggest in `async` functions
|
||||||
|
// to avoid complex logic or incorrect output.
|
||||||
|
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
|
||||||
|
ImplItemKind::Fn(ref sig, _)
|
||||||
|
if sig.header.asyncness == hir::IsAsync::NotAsync =>
|
||||||
|
{
|
||||||
|
let msg = "change the output type to match the trait";
|
||||||
|
let ap = Applicability::MachineApplicable;
|
||||||
|
match sig.decl.output {
|
||||||
|
hir::FnRetTy::DefaultReturn(sp) => {
|
||||||
|
let sugg = format!("-> {} ", trait_sig.output());
|
||||||
|
diag.span_suggestion_verbose(sp, msg, sugg, ap);
|
||||||
|
}
|
||||||
|
hir::FnRetTy::Return(hir_ty) => {
|
||||||
|
let sugg = trait_sig.output();
|
||||||
|
diag.span_suggestion(hir_ty.span, msg, sugg, ap);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
} else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
|
||||||
|
diag.span_suggestion(
|
||||||
|
impl_err_span,
|
||||||
|
"change the parameter type to match the trait",
|
||||||
|
trait_ty,
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
infcx.err_ctxt().note_type_err(
|
||||||
|
&mut diag,
|
||||||
|
&cause,
|
||||||
|
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
|
||||||
|
Some(infer::ValuePairs::Terms(ExpectedFound {
|
||||||
|
expected: trait_fty.into(),
|
||||||
|
found: impl_fty.into(),
|
||||||
|
})),
|
||||||
|
terr,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
return diag.emit();
|
||||||
|
}
|
||||||
|
|
||||||
fn check_region_bounds_on_impl_item<'tcx>(
|
fn check_region_bounds_on_impl_item<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_m: &ty::AssocItem,
|
impl_m: &ty::AssocItem,
|
||||||
|
|
|
@ -18,6 +18,7 @@ use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryRespons
|
||||||
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
|
||||||
use rustc_infer::infer::{InferOk, InferResult};
|
use rustc_infer::infer::{InferOk, InferResult};
|
||||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||||
|
use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::fold::TypeFoldable;
|
use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::visit::TypeVisitable;
|
use rustc_middle::ty::visit::TypeVisitable;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
|
@ -32,9 +33,7 @@ use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||||
self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
@ -766,34 +765,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let expect_args = self
|
let expect_args = self
|
||||||
.fudge_inference_if_ok(|| {
|
.fudge_inference_if_ok(|| {
|
||||||
|
let ocx = ObligationCtxt::new_in_snapshot(self);
|
||||||
|
|
||||||
// Attempt to apply a subtyping relationship between the formal
|
// Attempt to apply a subtyping relationship between the formal
|
||||||
// return type (likely containing type variables if the function
|
// return type (likely containing type variables if the function
|
||||||
// is polymorphic) and the expected return type.
|
// is polymorphic) and the expected return type.
|
||||||
// No argument expectations are produced if unification fails.
|
// No argument expectations are produced if unification fails.
|
||||||
let origin = self.misc(call_span);
|
let origin = self.misc(call_span);
|
||||||
let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
|
ocx.sup(&origin, self.param_env, ret_ty, formal_ret)?;
|
||||||
|
if !ocx.select_where_possible().is_empty() {
|
||||||
// FIXME(#27336) can't use ? here, Try::from_error doesn't default
|
return Err(TypeError::Mismatch);
|
||||||
// to identity so the resulting type is not constrained.
|
|
||||||
match ures {
|
|
||||||
Ok(ok) => {
|
|
||||||
// Process any obligations locally as much as
|
|
||||||
// we can. We don't care if some things turn
|
|
||||||
// out unconstrained or ambiguous, as we're
|
|
||||||
// just trying to get hints here.
|
|
||||||
let errors = self.save_and_restore_in_snapshot_flag(|_| {
|
|
||||||
let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
|
|
||||||
for obligation in ok.obligations {
|
|
||||||
fulfill.register_predicate_obligation(self, obligation);
|
|
||||||
}
|
|
||||||
fulfill.select_where_possible(self)
|
|
||||||
});
|
|
||||||
|
|
||||||
if !errors.is_empty() {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => return Err(()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record all the argument types, with the substitutions
|
// Record all the argument types, with the substitutions
|
||||||
|
|
|
@ -778,32 +778,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the "currently in a snapshot" flag, invoke the closure,
|
|
||||||
/// then restore the flag to its original value. This flag is a
|
|
||||||
/// debugging measure designed to detect cases where we start a
|
|
||||||
/// snapshot, create type variables, and register obligations
|
|
||||||
/// which may involve those type variables in the fulfillment cx,
|
|
||||||
/// potentially leaving "dangling type variables" behind.
|
|
||||||
/// In such cases, an assertion will fail when attempting to
|
|
||||||
/// register obligations, within a snapshot. Very useful, much
|
|
||||||
/// better than grovelling through megabytes of `RUSTC_LOG` output.
|
|
||||||
///
|
|
||||||
/// HOWEVER, in some cases the flag is unhelpful. In particular, we
|
|
||||||
/// sometimes create a "mini-fulfilment-cx" in which we enroll
|
|
||||||
/// obligations. As long as this fulfillment cx is fully drained
|
|
||||||
/// before we return, this is not a problem, as there won't be any
|
|
||||||
/// escaping obligations in the main cx. In those cases, you can
|
|
||||||
/// use this function.
|
|
||||||
pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(&Self) -> R,
|
|
||||||
{
|
|
||||||
let flag = self.in_snapshot.replace(false);
|
|
||||||
let result = func(self);
|
|
||||||
self.in_snapshot.set(flag);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
|
fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
|
||||||
debug!("start_snapshot()");
|
debug!("start_snapshot()");
|
||||||
|
|
||||||
|
|
|
@ -119,13 +119,13 @@ impl CheckAttrVisitor<'_> {
|
||||||
}
|
}
|
||||||
sym::naked => self.check_naked(hir_id, attr, span, target),
|
sym::naked => self.check_naked(hir_id, attr, span, target),
|
||||||
sym::rustc_legacy_const_generics => {
|
sym::rustc_legacy_const_generics => {
|
||||||
self.check_rustc_legacy_const_generics(&attr, span, target, item)
|
self.check_rustc_legacy_const_generics(hir_id, &attr, span, target, item)
|
||||||
}
|
}
|
||||||
sym::rustc_lint_query_instability => {
|
sym::rustc_lint_query_instability => {
|
||||||
self.check_rustc_lint_query_instability(&attr, span, target)
|
self.check_rustc_lint_query_instability(hir_id, &attr, span, target)
|
||||||
}
|
}
|
||||||
sym::rustc_lint_diagnostics => {
|
sym::rustc_lint_diagnostics => {
|
||||||
self.check_rustc_lint_diagnostics(&attr, span, target)
|
self.check_rustc_lint_diagnostics(hir_id, &attr, span, target)
|
||||||
}
|
}
|
||||||
sym::rustc_lint_opt_ty => self.check_rustc_lint_opt_ty(&attr, span, target),
|
sym::rustc_lint_opt_ty => self.check_rustc_lint_opt_ty(&attr, span, target),
|
||||||
sym::rustc_lint_opt_deny_field_access => {
|
sym::rustc_lint_opt_deny_field_access => {
|
||||||
|
@ -135,7 +135,9 @@ impl CheckAttrVisitor<'_> {
|
||||||
| sym::rustc_dirty
|
| sym::rustc_dirty
|
||||||
| sym::rustc_if_this_changed
|
| sym::rustc_if_this_changed
|
||||||
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
|
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
|
||||||
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
|
sym::cmse_nonsecure_entry => {
|
||||||
|
self.check_cmse_nonsecure_entry(hir_id, attr, span, target)
|
||||||
|
}
|
||||||
sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
|
sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target),
|
||||||
sym::const_trait => self.check_const_trait(attr, span, target),
|
sym::const_trait => self.check_const_trait(attr, span, target),
|
||||||
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
|
sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
|
||||||
|
@ -386,6 +388,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||||
attr_span: attr.span,
|
attr_span: attr.span,
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -393,7 +396,13 @@ impl CheckAttrVisitor<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition.
|
/// Checks if `#[cmse_nonsecure_entry]` is applied to a function definition.
|
||||||
fn check_cmse_nonsecure_entry(&self, attr: &Attribute, span: Span, target: Target) -> bool {
|
fn check_cmse_nonsecure_entry(
|
||||||
|
&self,
|
||||||
|
hir_id: HirId,
|
||||||
|
attr: &Attribute,
|
||||||
|
span: Span,
|
||||||
|
target: Target,
|
||||||
|
) -> bool {
|
||||||
match target {
|
match target {
|
||||||
Target::Fn
|
Target::Fn
|
||||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
|
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
|
||||||
|
@ -401,6 +410,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||||
attr_span: attr.span,
|
attr_span: attr.span,
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -465,9 +475,11 @@ impl CheckAttrVisitor<'_> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx
|
self.tcx.sess.emit_err(errors::TrackedCallerWrongLocation {
|
||||||
.sess
|
attr_span,
|
||||||
.emit_err(errors::TrackedCallerWrongLocation { attr_span, defn_span: span });
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
|
});
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -576,6 +588,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||||
attr_span: attr.span,
|
attr_span: attr.span,
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -1230,7 +1243,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
UNUSED_ATTRIBUTES,
|
UNUSED_ATTRIBUTES,
|
||||||
hir_id,
|
hir_id,
|
||||||
attr.span,
|
attr.span,
|
||||||
errors::Cold { span },
|
errors::Cold { span, on_crate: hir_id == CRATE_HIR_ID },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1366,6 +1379,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
|
/// Checks if `#[rustc_legacy_const_generics]` is applied to a function and has a valid argument.
|
||||||
fn check_rustc_legacy_const_generics(
|
fn check_rustc_legacy_const_generics(
|
||||||
&self,
|
&self,
|
||||||
|
hir_id: HirId,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
span: Span,
|
span: Span,
|
||||||
target: Target,
|
target: Target,
|
||||||
|
@ -1376,6 +1390,7 @@ impl CheckAttrVisitor<'_> {
|
||||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||||
attr_span: attr.span,
|
attr_span: attr.span,
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1440,12 +1455,19 @@ impl CheckAttrVisitor<'_> {
|
||||||
|
|
||||||
/// Helper function for checking that the provided attribute is only applied to a function or
|
/// Helper function for checking that the provided attribute is only applied to a function or
|
||||||
/// method.
|
/// method.
|
||||||
fn check_applied_to_fn_or_method(&self, attr: &Attribute, span: Span, target: Target) -> bool {
|
fn check_applied_to_fn_or_method(
|
||||||
|
&self,
|
||||||
|
hir_id: HirId,
|
||||||
|
attr: &Attribute,
|
||||||
|
span: Span,
|
||||||
|
target: Target,
|
||||||
|
) -> bool {
|
||||||
let is_function = matches!(target, Target::Fn | Target::Method(..));
|
let is_function = matches!(target, Target::Fn | Target::Method(..));
|
||||||
if !is_function {
|
if !is_function {
|
||||||
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToFn {
|
||||||
attr_span: attr.span,
|
attr_span: attr.span,
|
||||||
defn_span: span,
|
defn_span: span,
|
||||||
|
on_crate: hir_id == CRATE_HIR_ID,
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
|
@ -1457,17 +1479,24 @@ impl CheckAttrVisitor<'_> {
|
||||||
/// or method.
|
/// or method.
|
||||||
fn check_rustc_lint_query_instability(
|
fn check_rustc_lint_query_instability(
|
||||||
&self,
|
&self,
|
||||||
|
hir_id: HirId,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
span: Span,
|
span: Span,
|
||||||
target: Target,
|
target: Target,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
self.check_applied_to_fn_or_method(attr, span, target)
|
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or
|
/// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or
|
||||||
/// method.
|
/// method.
|
||||||
fn check_rustc_lint_diagnostics(&self, attr: &Attribute, span: Span, target: Target) -> bool {
|
fn check_rustc_lint_diagnostics(
|
||||||
self.check_applied_to_fn_or_method(attr, span, target)
|
&self,
|
||||||
|
hir_id: HirId,
|
||||||
|
attr: &Attribute,
|
||||||
|
span: Span,
|
||||||
|
target: Target,
|
||||||
|
) -> bool {
|
||||||
|
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.
|
/// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.
|
||||||
|
|
|
@ -81,6 +81,7 @@ pub struct AttrShouldBeAppliedToFn {
|
||||||
pub attr_span: Span,
|
pub attr_span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
pub defn_span: Span,
|
pub defn_span: Span,
|
||||||
|
pub on_crate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -97,6 +98,7 @@ pub struct TrackedCallerWrongLocation {
|
||||||
pub attr_span: Span,
|
pub attr_span: Span,
|
||||||
#[label]
|
#[label]
|
||||||
pub defn_span: Span,
|
pub defn_span: Span,
|
||||||
|
pub on_crate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -367,6 +369,7 @@ pub struct MustNotSuspend {
|
||||||
pub struct Cold {
|
pub struct Cold {
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub on_crate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
#[derive(LintDiagnostic)]
|
||||||
|
|
|
@ -241,10 +241,12 @@ impl<'a> Resolver<'a> {
|
||||||
));
|
));
|
||||||
|
|
||||||
err.span_label(span, format!("`{}` re{} here", name, new_participle));
|
err.span_label(span, format!("`{}` re{} here", name, new_participle));
|
||||||
|
if !old_binding.span.is_dummy() && old_binding.span != span {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
self.session.source_map().guess_head_span(old_binding.span),
|
self.session.source_map().guess_head_span(old_binding.span),
|
||||||
format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
|
format!("previous {} of the {} `{}` here", old_noun, old_kind, name),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// See https://github.com/rust-lang/rust/issues/32354
|
// See https://github.com/rust-lang/rust/issues/32354
|
||||||
use NameBindingKind::Import;
|
use NameBindingKind::Import;
|
||||||
|
|
|
@ -807,6 +807,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
err.code(rustc_errors::error_code!(E0411));
|
err.code(rustc_errors::error_code!(E0411));
|
||||||
err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
|
err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
|
||||||
if let Some(item_kind) = self.diagnostic_metadata.current_item {
|
if let Some(item_kind) = self.diagnostic_metadata.current_item {
|
||||||
|
if !item_kind.ident.span.is_dummy() {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
item_kind.ident.span,
|
item_kind.ident.span,
|
||||||
format!(
|
format!(
|
||||||
|
@ -816,6 +817,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||||
has_derive_copy: false,
|
has_derive_copy: false,
|
||||||
});
|
});
|
||||||
let parent_scope = self.invocation_parent_scopes[&expn_id];
|
let parent_scope = self.invocation_parent_scopes[&expn_id];
|
||||||
for (i, (path, _, opt_ext)) in entry.resolutions.iter_mut().enumerate() {
|
for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() {
|
||||||
if opt_ext.is_none() {
|
if opt_ext.is_none() {
|
||||||
*opt_ext = Some(
|
*opt_ext = Some(
|
||||||
match self.resolve_macro_path(
|
match self.resolve_macro_path(
|
||||||
|
|
|
@ -620,6 +620,7 @@ symbols! {
|
||||||
deref_mut,
|
deref_mut,
|
||||||
deref_target,
|
deref_target,
|
||||||
derive,
|
derive,
|
||||||
|
derive_const,
|
||||||
derive_default_enum,
|
derive_default_enum,
|
||||||
destruct,
|
destruct,
|
||||||
destructuring_assignment,
|
destructuring_assignment,
|
||||||
|
|
|
@ -2445,12 +2445,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
(Ok(l), Ok(r)) => l.line == r.line,
|
(Ok(l), Ok(r)) => l.line == r.line,
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
if !ident.span.overlaps(span) && !same_line {
|
if !ident.span.is_dummy() && !ident.span.overlaps(span) && !same_line {
|
||||||
multispan.push_span_label(ident.span, "required by a bound in this");
|
multispan.push_span_label(ident.span, "required by a bound in this");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let descr = format!("required by a bound in `{}`", item_name);
|
let descr = format!("required by a bound in `{}`", item_name);
|
||||||
if span != DUMMY_SP {
|
if !span.is_dummy() {
|
||||||
let msg = format!("required by this bound in `{}`", item_name);
|
let msg = format!("required by this bound in `{}`", item_name);
|
||||||
multispan.push_span_label(span, msg);
|
multispan.push_span_label(span, msg);
|
||||||
err.span_note(multispan, &descr);
|
err.span_note(multispan, &descr);
|
||||||
|
|
|
@ -10,10 +10,12 @@
|
||||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html
|
||||||
|
|
||||||
pub mod specialization_graph;
|
pub mod specialization_graph;
|
||||||
|
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _};
|
||||||
use specialization_graph::GraphExt;
|
use specialization_graph::GraphExt;
|
||||||
|
|
||||||
use crate::errors::NegativePositiveConflict;
|
use crate::errors::NegativePositiveConflict;
|
||||||
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||||
|
use crate::traits::engine::TraitEngineExt as _;
|
||||||
use crate::traits::select::IntercrateAmbiguityCause;
|
use crate::traits::select::IntercrateAmbiguityCause;
|
||||||
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
|
@ -200,23 +202,15 @@ fn fulfill_implication<'tcx>(
|
||||||
return Err(());
|
return Err(());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Needs to be `in_snapshot` because this function is used to rebase
|
||||||
|
// substitutions, which may happen inside of a select within a probe.
|
||||||
|
let mut engine = <dyn TraitEngine<'tcx>>::new_in_snapshot(infcx.tcx);
|
||||||
// attempt to prove all of the predicates for impl2 given those for impl1
|
// attempt to prove all of the predicates for impl2 given those for impl1
|
||||||
// (which are packed up in penv)
|
// (which are packed up in penv)
|
||||||
|
engine.register_predicate_obligations(infcx, obligations.chain(more_obligations));
|
||||||
|
|
||||||
infcx.save_and_restore_in_snapshot_flag(|infcx| {
|
let errors = engine.select_all_or_error(infcx);
|
||||||
let errors = traits::fully_solve_obligations(&infcx, obligations.chain(more_obligations));
|
if !errors.is_empty() {
|
||||||
match &errors[..] {
|
|
||||||
[] => {
|
|
||||||
debug!(
|
|
||||||
"fulfill_implication: an impl for {:?} specializes {:?}",
|
|
||||||
source_trait, target_trait
|
|
||||||
);
|
|
||||||
|
|
||||||
// Now resolve the *substitution* we built for the target earlier, replacing
|
|
||||||
// the inference variables inside with whatever we got from fulfillment.
|
|
||||||
Ok(infcx.resolve_vars_if_possible(target_substs))
|
|
||||||
}
|
|
||||||
errors => {
|
|
||||||
// no dice!
|
// no dice!
|
||||||
debug!(
|
debug!(
|
||||||
"fulfill_implication: for impls on {:?} and {:?}, \
|
"fulfill_implication: for impls on {:?} and {:?}, \
|
||||||
|
@ -226,10 +220,14 @@ fn fulfill_implication<'tcx>(
|
||||||
errors,
|
errors,
|
||||||
param_env.caller_bounds()
|
param_env.caller_bounds()
|
||||||
);
|
);
|
||||||
Err(())
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait);
|
||||||
|
|
||||||
|
// Now resolve the *substitution* we built for the target earlier, replacing
|
||||||
|
// the inference variables inside with whatever we got from fulfillment.
|
||||||
|
Ok(infcx.resolve_vars_if_possible(target_substs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query provider for `specialization_graph_of`.
|
// Query provider for `specialization_graph_of`.
|
||||||
|
|
|
@ -2,20 +2,18 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::TraitEngineExt as _;
|
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::InternalSubsts;
|
use rustc_middle::ty::InternalSubsts;
|
||||||
use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt};
|
use rustc_middle::ty::{self, EarlyBinder, ParamEnvAnd, Ty, TyCtxt};
|
||||||
use rustc_span::source_map::{Span, DUMMY_SP};
|
use rustc_span::source_map::{Span, DUMMY_SP};
|
||||||
|
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
||||||
use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outlives;
|
use rustc_trait_selection::traits::query::dropck_outlives::trivial_dropck_outlives;
|
||||||
use rustc_trait_selection::traits::query::dropck_outlives::{
|
use rustc_trait_selection::traits::query::dropck_outlives::{
|
||||||
DropckConstraint, DropckOutlivesResult,
|
DropckConstraint, DropckOutlivesResult,
|
||||||
};
|
};
|
||||||
use rustc_trait_selection::traits::query::normalize::AtExt;
|
use rustc_trait_selection::traits::query::normalize::AtExt;
|
||||||
use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution};
|
use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution};
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{Normalized, ObligationCause};
|
||||||
Normalized, ObligationCause, TraitEngine, TraitEngineExt as _,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) fn provide(p: &mut Providers) {
|
pub(crate) fn provide(p: &mut Providers) {
|
||||||
*p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p };
|
*p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p };
|
||||||
|
@ -27,9 +25,8 @@ fn dropck_outlives<'tcx>(
|
||||||
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> {
|
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>, NoSolution> {
|
||||||
debug!("dropck_outlives(goal={:#?})", canonical_goal);
|
debug!("dropck_outlives(goal={:#?})", canonical_goal);
|
||||||
|
|
||||||
let (ref infcx, goal, canonical_inference_vars) =
|
tcx.infer_ctxt().enter_canonical_trait_query(&canonical_goal, |ocx, goal| {
|
||||||
tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal);
|
let tcx = ocx.infcx.tcx;
|
||||||
let tcx = infcx.tcx;
|
|
||||||
let ParamEnvAnd { param_env, value: for_ty } = goal;
|
let ParamEnvAnd { param_env, value: for_ty } = goal;
|
||||||
|
|
||||||
let mut result = DropckOutlivesResult { kinds: vec![], overflows: vec![] };
|
let mut result = DropckOutlivesResult { kinds: vec![], overflows: vec![] };
|
||||||
|
@ -73,8 +70,6 @@ fn dropck_outlives<'tcx>(
|
||||||
// Set used to detect infinite recursion.
|
// Set used to detect infinite recursion.
|
||||||
let mut ty_set = FxHashSet::default();
|
let mut ty_set = FxHashSet::default();
|
||||||
|
|
||||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
|
||||||
|
|
||||||
let cause = ObligationCause::dummy();
|
let cause = ObligationCause::dummy();
|
||||||
let mut constraints = DropckConstraint::empty();
|
let mut constraints = DropckConstraint::empty();
|
||||||
while let Some((ty, depth)) = ty_stack.pop() {
|
while let Some((ty, depth)) = ty_stack.pop() {
|
||||||
|
@ -104,9 +99,9 @@ fn dropck_outlives<'tcx>(
|
||||||
// do not themselves define a destructor", more or less. We have
|
// do not themselves define a destructor", more or less. We have
|
||||||
// to push them onto the stack to be expanded.
|
// to push them onto the stack to be expanded.
|
||||||
for ty in constraints.dtorck_types.drain(..) {
|
for ty in constraints.dtorck_types.drain(..) {
|
||||||
match infcx.at(&cause, param_env).normalize(ty) {
|
let Normalized { value: ty, obligations } =
|
||||||
Ok(Normalized { value: ty, obligations }) => {
|
ocx.infcx.at(&cause, param_env).normalize(ty)?;
|
||||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
ocx.register_obligations(obligations);
|
||||||
|
|
||||||
debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
|
debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
|
||||||
|
|
||||||
|
@ -128,19 +123,11 @@ fn dropck_outlives<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't actually expect to fail to normalize.
|
|
||||||
// That implies a WF error somewhere else.
|
|
||||||
Err(NoSolution) => {
|
|
||||||
return Err(NoSolution);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("dropck_outlives: result = {:#?}", result);
|
debug!("dropck_outlives: result = {:#?}", result);
|
||||||
|
Ok(result)
|
||||||
infcx.make_canonicalized_query_response(canonical_inference_vars, result, &mut *fulfill_cx)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a set of constraints that needs to be satisfied in
|
/// Returns a set of constraints that needs to be satisfied in
|
||||||
|
|
|
@ -1464,6 +1464,19 @@ pub(crate) mod builtin {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attribute macro used to apply derive macros for implementing traits
|
||||||
|
/// in a const context.
|
||||||
|
///
|
||||||
|
/// See [the reference] for more info.
|
||||||
|
///
|
||||||
|
/// [the reference]: ../../../reference/attributes/derive.html
|
||||||
|
#[unstable(feature = "derive_const", issue = "none")]
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
pub macro derive_const($item:item) {
|
||||||
|
/* compiler built-in */
|
||||||
|
}
|
||||||
|
|
||||||
/// Attribute macro applied to a function to turn it into a unit test.
|
/// Attribute macro applied to a function to turn it into a unit test.
|
||||||
///
|
///
|
||||||
/// See [the reference] for more info.
|
/// See [the reference] for more info.
|
||||||
|
|
|
@ -81,6 +81,10 @@ pub use crate::macros::builtin::alloc_error_handler;
|
||||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||||
pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
|
pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
|
||||||
|
|
||||||
|
#[unstable(feature = "derive_const", issue = "none")]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
pub use crate::macros::builtin::derive_const;
|
||||||
|
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "cfg_accessible",
|
feature = "cfg_accessible",
|
||||||
issue = "64797",
|
issue = "64797",
|
||||||
|
|
|
@ -65,6 +65,10 @@ pub use core::prelude::v1::alloc_error_handler;
|
||||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||||
pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
|
pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
|
||||||
|
|
||||||
|
#[unstable(feature = "derive_const", issue = "none")]
|
||||||
|
#[cfg(not(bootstrap))]
|
||||||
|
pub use core::prelude::v1::derive_const;
|
||||||
|
|
||||||
// Do not `doc(no_inline)` either.
|
// Do not `doc(no_inline)` either.
|
||||||
#[unstable(
|
#[unstable(
|
||||||
feature = "cfg_accessible",
|
feature = "cfg_accessible",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-line .radio-line input {
|
.setting-line .radio-line input,
|
||||||
|
.setting-line .toggle input {
|
||||||
margin-right: 0.3em;
|
margin-right: 0.3em;
|
||||||
height: 1.2rem;
|
height: 1.2rem;
|
||||||
width: 1.2rem;
|
width: 1.2rem;
|
||||||
|
@ -17,9 +18,18 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.setting-line .radio-line input {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
.setting-line .radio-line input + span {
|
.setting-line .toggle input:checked {
|
||||||
|
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40">\
|
||||||
|
<path d="M7,25L17,32L33,12" fill="none" stroke="black" stroke-width="5"/>\
|
||||||
|
<path d="M7,23L17,30L33,10" fill="none" stroke="white" stroke-width="5"/></svg>');
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-line .radio-line input + span,
|
||||||
|
.setting-line .toggle span {
|
||||||
padding-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,37 +59,6 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle input {
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
position: relative;
|
|
||||||
width: 45px;
|
|
||||||
min-width: 45px;
|
|
||||||
display: block;
|
|
||||||
height: 28px;
|
|
||||||
margin-right: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #ccc;
|
|
||||||
transition: .3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider:before {
|
|
||||||
position: absolute;
|
|
||||||
content: "";
|
|
||||||
height: 19px;
|
|
||||||
width: 19px;
|
|
||||||
left: 4px;
|
|
||||||
bottom: 4px;
|
|
||||||
transition: .3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked + .slider:before {
|
|
||||||
transform: translateX(19px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-line > .sub-settings {
|
.setting-line > .sub-settings {
|
||||||
padding-left: 42px;
|
padding-left: 42px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -94,7 +73,11 @@ input:checked + .slider:before {
|
||||||
box-shadow: inset 0 0 0 3px var(--main-background-color);
|
box-shadow: inset 0 0 0 3px var(--main-background-color);
|
||||||
background-color: var(--settings-input-color);
|
background-color: var(--settings-input-color);
|
||||||
}
|
}
|
||||||
.setting-line .radio-line input:focus {
|
.setting-line .toggle input:checked {
|
||||||
|
background-color: var(--settings-input-color);
|
||||||
|
}
|
||||||
|
.setting-line .radio-line input:focus,
|
||||||
|
.setting-line .toggle input:focus {
|
||||||
box-shadow: 0 0 1px 1px var(--settings-input-color);
|
box-shadow: 0 0 1px 1px var(--settings-input-color);
|
||||||
}
|
}
|
||||||
/* In here we combine both `:focus` and `:checked` properties. */
|
/* In here we combine both `:focus` and `:checked` properties. */
|
||||||
|
@ -102,9 +85,7 @@ input:checked + .slider:before {
|
||||||
box-shadow: inset 0 0 0 3px var(--main-background-color),
|
box-shadow: inset 0 0 0 3px var(--main-background-color),
|
||||||
0 0 2px 2px var(--settings-input-color);
|
0 0 2px 2px var(--settings-input-color);
|
||||||
}
|
}
|
||||||
.setting-line .radio-line input:hover {
|
.setting-line .radio-line input:hover,
|
||||||
|
.setting-line .toggle input:hover {
|
||||||
border-color: var(--settings-input-color) !important;
|
border-color: var(--settings-input-color) !important;
|
||||||
}
|
}
|
||||||
input:checked + .slider {
|
|
||||||
background-color: var(--settings-input-color);
|
|
||||||
}
|
|
||||||
|
|
|
@ -77,16 +77,6 @@ Original by Dempfi (https://github.com/dempfi/ayu)
|
||||||
--crate-search-hover-border: #e0e0e0;
|
--crate-search-hover-border: #e0e0e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
.slider:before {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
input:focus + .slider {
|
|
||||||
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
h1, h2, h3, h4 {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,16 +72,6 @@
|
||||||
--crate-search-hover-border: #2196f3;
|
--crate-search-hover-border: #2196f3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
.slider:before {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
input:focus + .slider {
|
|
||||||
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content .item-info::before { color: #ccc; }
|
.content .item-info::before { color: #ccc; }
|
||||||
|
|
||||||
body.source .example-wrap pre.rust a {
|
body.source .example-wrap pre.rust a {
|
||||||
|
|
|
@ -69,15 +69,6 @@
|
||||||
--crate-search-hover-border: #717171;
|
--crate-search-hover-border: #717171;
|
||||||
}
|
}
|
||||||
|
|
||||||
.slider {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
.slider:before {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
input:focus + .slider {
|
|
||||||
box-shadow: 0 0 0 2px #0a84ff, 0 0 0 6px rgba(10, 132, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content .item-info::before { color: #ccc; }
|
.content .item-info::before { color: #ccc; }
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@
|
||||||
|
|
||||||
function setEvents(settingsElement) {
|
function setEvents(settingsElement) {
|
||||||
updateLightAndDark();
|
updateLightAndDark();
|
||||||
onEachLazy(settingsElement.getElementsByClassName("slider"), elem => {
|
onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"), toggle => {
|
||||||
const toggle = elem.previousElementSibling;
|
|
||||||
const settingId = toggle.id;
|
const settingId = toggle.id;
|
||||||
const settingValue = getSettingValue(settingId);
|
const settingValue = getSettingValue(settingId);
|
||||||
if (settingValue !== null) {
|
if (settingValue !== null) {
|
||||||
|
@ -139,7 +138,6 @@
|
||||||
const checked = setting["default"] === true ? " checked" : "";
|
const checked = setting["default"] === true ? " checked" : "";
|
||||||
output += `<label class="toggle">\
|
output += `<label class="toggle">\
|
||||||
<input type="checkbox" id="${js_data_name}"${checked}>\
|
<input type="checkbox" id="${js_data_name}"${checked}>\
|
||||||
<span class="slider"></span>\
|
|
||||||
<span class="label">${setting_name}</span>\
|
<span class="label">${setting_name}</span>\
|
||||||
</label>`;
|
</label>`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,10 @@ wait-for: "#settings"
|
||||||
assert-css: ("#settings", {"display": "block"})
|
assert-css: ("#settings", {"display": "block"})
|
||||||
|
|
||||||
// Then, click the toggle button.
|
// Then, click the toggle button.
|
||||||
click: "input#line-numbers + .slider"
|
click: "input#line-numbers"
|
||||||
wait-for: 100 // wait-for-false does not exist
|
wait-for: 100 // wait-for-false does not exist
|
||||||
assert-false: "pre.example-line-numbers"
|
assert-false: "pre.example-line-numbers"
|
||||||
|
|
||||||
// Finally, turn it on again.
|
// Finally, turn it on again.
|
||||||
click: "input#line-numbers + .slider"
|
click: "input#line-numbers"
|
||||||
wait-for: "pre.example-line-numbers"
|
wait-for: "pre.example-line-numbers"
|
||||||
|
|
|
@ -48,7 +48,8 @@ assert: ".setting-line.hidden #preferred-light-theme"
|
||||||
assert-property: ("#theme .choices #theme-dark", {"checked": "true"})
|
assert-property: ("#theme .choices #theme-dark", {"checked": "true"})
|
||||||
|
|
||||||
// Some style checks...
|
// Some style checks...
|
||||||
// First we check the "default" display.
|
move-cursor-to: "#settings-menu > a"
|
||||||
|
// First we check the "default" display for radio buttons.
|
||||||
assert-css: (
|
assert-css: (
|
||||||
"#theme-dark",
|
"#theme-dark",
|
||||||
{
|
{
|
||||||
|
@ -57,7 +58,7 @@ assert-css: (
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"})
|
assert-css: ("#theme-light", {"border-color": "rgb(221, 221, 221)", "box-shadow": "none"})
|
||||||
// Let's start with the hover.
|
// Let's start with the hover for radio buttons.
|
||||||
move-cursor-to: "#theme-dark"
|
move-cursor-to: "#theme-dark"
|
||||||
assert-css: (
|
assert-css: (
|
||||||
"#theme-dark",
|
"#theme-dark",
|
||||||
|
@ -69,7 +70,7 @@ assert-css: (
|
||||||
move-cursor-to: "#theme-light"
|
move-cursor-to: "#theme-light"
|
||||||
assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"})
|
assert-css: ("#theme-light", {"border-color": "rgb(33, 150, 243)", "box-shadow": "none"})
|
||||||
move-cursor-to: "#theme-ayu"
|
move-cursor-to: "#theme-ayu"
|
||||||
// Let's now check with the focus.
|
// Let's now check with the focus for radio buttons.
|
||||||
focus: "#theme-dark"
|
focus: "#theme-dark"
|
||||||
assert-css: (
|
assert-css: (
|
||||||
"#theme-dark",
|
"#theme-dark",
|
||||||
|
@ -86,7 +87,7 @@ assert-css: (
|
||||||
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
// Now we check we both focus and hover.
|
// Now we check we both focus and hover for radio buttons.
|
||||||
move-cursor-to: "#theme-dark"
|
move-cursor-to: "#theme-dark"
|
||||||
focus: "#theme-dark"
|
focus: "#theme-dark"
|
||||||
assert-css: (
|
assert-css: (
|
||||||
|
@ -106,6 +107,80 @@ assert-css: (
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// First we check the "default" display for toggles.
|
||||||
|
assert-css: (
|
||||||
|
"#auto-hide-large-items",
|
||||||
|
{
|
||||||
|
"background-color": "rgb(33, 150, 243)",
|
||||||
|
"border-color": "rgb(221, 221, 221)",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert-css: (
|
||||||
|
"#use-system-theme",
|
||||||
|
{
|
||||||
|
"background-color": "rgba(0, 0, 0, 0)",
|
||||||
|
"border-color": "rgb(221, 221, 221)",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// Let's start with the hover for toggles.
|
||||||
|
move-cursor-to: "#auto-hide-large-items"
|
||||||
|
assert-css: (
|
||||||
|
"#auto-hide-large-items",
|
||||||
|
{
|
||||||
|
"background-color": "rgb(33, 150, 243)",
|
||||||
|
"border-color": "rgb(33, 150, 243)",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
move-cursor-to: "#use-system-theme"
|
||||||
|
assert-css: (
|
||||||
|
"#use-system-theme",
|
||||||
|
{
|
||||||
|
"background-color": "rgba(0, 0, 0, 0)",
|
||||||
|
"border-color": "rgb(33, 150, 243)",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
move-cursor-to: "#settings-menu > a"
|
||||||
|
// Let's now check with the focus for toggles.
|
||||||
|
focus: "#auto-hide-large-items"
|
||||||
|
assert-css: (
|
||||||
|
"#auto-hide-large-items",
|
||||||
|
{
|
||||||
|
"background-color": "rgb(33, 150, 243)",
|
||||||
|
"border-color": "rgb(221, 221, 221)",
|
||||||
|
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
focus: "#use-system-theme"
|
||||||
|
assert-css: (
|
||||||
|
"#use-system-theme",
|
||||||
|
{
|
||||||
|
"background-color": "rgba(0, 0, 0, 0)",
|
||||||
|
"border-color": "rgb(221, 221, 221)",
|
||||||
|
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
// Now we check we both focus and hover for toggles.
|
||||||
|
move-cursor-to: "#auto-hide-large-items"
|
||||||
|
focus: "#auto-hide-large-items"
|
||||||
|
assert-css: (
|
||||||
|
"#auto-hide-large-items",
|
||||||
|
{
|
||||||
|
"background-color": "rgb(33, 150, 243)",
|
||||||
|
"border-color": "rgb(33, 150, 243)",
|
||||||
|
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
move-cursor-to: "#use-system-theme"
|
||||||
|
focus: "#use-system-theme"
|
||||||
|
assert-css: (
|
||||||
|
"#use-system-theme",
|
||||||
|
{
|
||||||
|
"background-color": "rgba(0, 0, 0, 0)",
|
||||||
|
"border-color": "rgb(33, 150, 243)",
|
||||||
|
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
// We now switch the display.
|
// We now switch the display.
|
||||||
click: "#use-system-theme"
|
click: "#use-system-theme"
|
||||||
// Wait for the hidden element to show up.
|
// Wait for the hidden element to show up.
|
||||||
|
@ -118,7 +193,7 @@ assert: ".setting-line.hidden #theme"
|
||||||
assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
|
assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
|
||||||
assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme")
|
assert-text: ("#preferred-light-theme .setting-name", "Preferred light theme")
|
||||||
|
|
||||||
// We now check that clicking on the "sliders"' text is like clicking on the slider.
|
// We now check that clicking on the toggles' text is like clicking on the checkbox.
|
||||||
// To test it, we use the "Disable keyboard shortcuts".
|
// To test it, we use the "Disable keyboard shortcuts".
|
||||||
local-storage: {"rustdoc-disable-shortcuts": "false"}
|
local-storage: {"rustdoc-disable-shortcuts": "false"}
|
||||||
click: ".setting-line:last-child .toggle .label"
|
click: ".setting-line:last-child .toggle .label"
|
||||||
|
@ -141,10 +216,7 @@ assert-css: ("#settings-menu .popover", {"display": "none"})
|
||||||
// Now we go to the settings page to check that the CSS is loaded as expected.
|
// Now we go to the settings page to check that the CSS is loaded as expected.
|
||||||
goto: "file://" + |DOC_PATH| + "/settings.html"
|
goto: "file://" + |DOC_PATH| + "/settings.html"
|
||||||
wait-for: "#settings"
|
wait-for: "#settings"
|
||||||
assert-css: (
|
assert-css: (".setting-line", {"position": "relative"})
|
||||||
".setting-line .toggle .slider",
|
|
||||||
{"width": "45px", "margin-right": "20px", "border": "0px none rgb(0, 0, 0)"},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
|
assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS)
|
||||||
compare-elements-position: (".sub form", "#settings", ("x"))
|
compare-elements-position: (".sub form", "#settings", ("x"))
|
||||||
|
@ -162,4 +234,4 @@ reload:
|
||||||
size: (300, 1000)
|
size: (300, 1000)
|
||||||
click: "#settings-menu"
|
click: "#settings-menu"
|
||||||
wait-for: "#settings"
|
wait-for: "#settings"
|
||||||
assert-css: ("#settings .slider", {"width": "45px"}, ALL)
|
assert-css: (".setting-line", {"position": "relative"})
|
||||||
|
|
|
@ -36,7 +36,7 @@ error: attribute should be applied to a function definition
|
||||||
--> $DIR/naked-invalid-attr.rs:5:1
|
--> $DIR/naked-invalid-attr.rs:5:1
|
||||||
|
|
|
|
||||||
LL | #![naked]
|
LL | #![naked]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ cannot be applied to crates
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -110,19 +110,19 @@ error: attribute should be applied to an `extern crate` item
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1
|
||||||
|
|
|
|
||||||
LL | #![no_link]
|
LL | #![no_link]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^ not an `extern crate` item
|
||||||
|
|
||||||
error: attribute should be applied to a free function, impl method or static
|
error: attribute should be applied to a free function, impl method or static
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:27:1
|
||||||
|
|
|
|
||||||
LL | #![export_name = "2200"]
|
LL | #![export_name = "2200"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ not a free function, impl method or static
|
||||||
|
|
||||||
error[E0518]: attribute should be applied to function or closure
|
error[E0518]: attribute should be applied to function or closure
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:29:1
|
||||||
|
|
|
|
||||||
LL | #![inline]
|
LL | #![inline]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not a function or closure
|
||||||
|
|
||||||
error: `macro_export` attribute cannot be used at crate level
|
error: `macro_export` attribute cannot be used at crate level
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//~ NOTE not a function
|
//~ NOTE not a function
|
||||||
//~| NOTE not a foreign function or static
|
//~| NOTE not a foreign function or static
|
||||||
//~| NOTE not a function or static
|
//~| NOTE cannot be applied to crates
|
||||||
//~| NOTE not an `extern` block
|
//~| NOTE not an `extern` block
|
||||||
// This test enumerates as many compiler-builtin ungated attributes as
|
// This test enumerates as many compiler-builtin ungated attributes as
|
||||||
// possible (that is, all the mutually compatible ones), and checks
|
// possible (that is, all the mutually compatible ones), and checks
|
||||||
|
|
|
@ -403,7 +403,7 @@ warning: attribute should be applied to a function definition
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
|
||||||
|
|
|
|
||||||
LL | #![cold]
|
LL | #![cold]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ cannot be applied to crates
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ warning: attribute should be applied to an `extern` block with non-Rust ABI
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
|
||||||
|
|
|
|
||||||
LL | #![link()]
|
LL | #![link()]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ not an `extern` block
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ warning: attribute should be applied to a foreign function or static
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
|
||||||
|
|
|
|
||||||
LL | #![link_name = "1900"]
|
LL | #![link_name = "1900"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^ not a foreign function or static
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
|
||||||
|
@ -427,7 +427,7 @@ warning: attribute should be applied to a function or static
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
|
||||||
|
|
|
|
||||||
LL | #![link_section = "1800"]
|
LL | #![link_section = "1800"]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not a function or static
|
||||||
|
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
|
||||||
|
|
51
src/test/ui/impl-trait/in-trait/method-signature-matches.rs
Normal file
51
src/test/ui/impl-trait/in-trait/method-signature-matches.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// edition: 2021
|
||||||
|
|
||||||
|
#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Uwu {
|
||||||
|
fn owo(x: ()) -> impl Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Uwu for () {
|
||||||
|
fn owo(_: u8) {}
|
||||||
|
//~^ ERROR method `owo` has an incompatible type for trait
|
||||||
|
}
|
||||||
|
|
||||||
|
trait AsyncUwu {
|
||||||
|
async fn owo(x: ()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncUwu for () {
|
||||||
|
async fn owo(_: u8) {}
|
||||||
|
//~^ ERROR method `owo` has an incompatible type for trait
|
||||||
|
}
|
||||||
|
|
||||||
|
trait TooMuch {
|
||||||
|
fn calm_down_please() -> impl Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TooMuch for () {
|
||||||
|
fn calm_down_please(_: (), _: (), _: ()) {}
|
||||||
|
//~^ ERROR method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
|
||||||
|
}
|
||||||
|
|
||||||
|
trait TooLittle {
|
||||||
|
fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TooLittle for () {
|
||||||
|
fn come_on_a_little_more_effort() {}
|
||||||
|
//~^ ERROR method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Lifetimes {
|
||||||
|
fn early<'early, T>(x: &'early T) -> impl Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lifetimes for () {
|
||||||
|
fn early<'late, T>(_: &'late ()) {}
|
||||||
|
//~^ ERROR method `early` has an incompatible type for trait
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,84 @@
|
||||||
|
error[E0053]: method `owo` has an incompatible type for trait
|
||||||
|
--> $DIR/method-signature-matches.rs:11:15
|
||||||
|
|
|
||||||
|
LL | fn owo(_: u8) {}
|
||||||
|
| ^^
|
||||||
|
| |
|
||||||
|
| expected `()`, found `u8`
|
||||||
|
| help: change the parameter type to match the trait: `()`
|
||||||
|
|
|
||||||
|
note: type in trait
|
||||||
|
--> $DIR/method-signature-matches.rs:7:15
|
||||||
|
|
|
||||||
|
LL | fn owo(x: ()) -> impl Sized;
|
||||||
|
| ^^
|
||||||
|
= note: expected fn pointer `fn(())`
|
||||||
|
found fn pointer `fn(u8)`
|
||||||
|
|
||||||
|
error[E0053]: method `owo` has an incompatible type for trait
|
||||||
|
--> $DIR/method-signature-matches.rs:20:21
|
||||||
|
|
|
||||||
|
LL | async fn owo(_: u8) {}
|
||||||
|
| ^^
|
||||||
|
| |
|
||||||
|
| expected `()`, found `u8`
|
||||||
|
| help: change the parameter type to match the trait: `()`
|
||||||
|
|
|
||||||
|
note: while checking the return type of the `async fn`
|
||||||
|
--> $DIR/method-signature-matches.rs:20:25
|
||||||
|
|
|
||||||
|
LL | async fn owo(_: u8) {}
|
||||||
|
| ^ checked the `Output` of this `async fn`, expected opaque type
|
||||||
|
note: while checking the return type of the `async fn`
|
||||||
|
--> $DIR/method-signature-matches.rs:20:25
|
||||||
|
|
|
||||||
|
LL | async fn owo(_: u8) {}
|
||||||
|
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||||
|
note: type in trait
|
||||||
|
--> $DIR/method-signature-matches.rs:16:21
|
||||||
|
|
|
||||||
|
LL | async fn owo(x: ()) {}
|
||||||
|
| ^^
|
||||||
|
= note: expected fn pointer `fn(()) -> _`
|
||||||
|
found fn pointer `fn(u8) -> _`
|
||||||
|
|
||||||
|
error[E0050]: method `calm_down_please` has 3 parameters but the declaration in trait `TooMuch::calm_down_please` has 0
|
||||||
|
--> $DIR/method-signature-matches.rs:29:28
|
||||||
|
|
|
||||||
|
LL | fn calm_down_please() -> impl Sized;
|
||||||
|
| ------------------------------------ trait requires 0 parameters
|
||||||
|
...
|
||||||
|
LL | fn calm_down_please(_: (), _: (), _: ()) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ expected 0 parameters, found 3
|
||||||
|
|
||||||
|
error[E0050]: method `come_on_a_little_more_effort` has 0 parameters but the declaration in trait `TooLittle::come_on_a_little_more_effort` has 3
|
||||||
|
--> $DIR/method-signature-matches.rs:38:5
|
||||||
|
|
|
||||||
|
LL | fn come_on_a_little_more_effort(_: (), _: (), _: ()) -> impl Sized;
|
||||||
|
| ---------------- trait requires 3 parameters
|
||||||
|
...
|
||||||
|
LL | fn come_on_a_little_more_effort() {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 3 parameters, found 0
|
||||||
|
|
||||||
|
error[E0053]: method `early` has an incompatible type for trait
|
||||||
|
--> $DIR/method-signature-matches.rs:47:27
|
||||||
|
|
|
||||||
|
LL | fn early<'late, T>(_: &'late ()) {}
|
||||||
|
| - ^^^^^^^^^
|
||||||
|
| | |
|
||||||
|
| | expected type parameter `T`, found `()`
|
||||||
|
| | help: change the parameter type to match the trait: `&'early T`
|
||||||
|
| this type parameter
|
||||||
|
|
|
||||||
|
note: type in trait
|
||||||
|
--> $DIR/method-signature-matches.rs:43:28
|
||||||
|
|
|
||||||
|
LL | fn early<'early, T>(x: &'early T) -> impl Sized;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
= note: expected fn pointer `fn(&'early T)`
|
||||||
|
found fn pointer `fn(&())`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0050, E0053.
|
||||||
|
For more information about an error, try `rustc --explain E0050`.
|
|
@ -2,18 +2,28 @@ error: cannot find attribute `derive_Clone` in this scope
|
||||||
--> $DIR/issue-32655.rs:3:11
|
--> $DIR/issue-32655.rs:3:11
|
||||||
|
|
|
|
||||||
LL | #[derive_Clone]
|
LL | #[derive_Clone]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
|
||||||
...
|
...
|
||||||
LL | foo!();
|
LL | foo!();
|
||||||
| ------ in this macro invocation
|
| ------ in this macro invocation
|
||||||
|
|
|
|
||||||
|
::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub macro derive_const($item:item) {
|
||||||
|
| ---------------------- similarly named attribute macro `derive_const` defined here
|
||||||
|
|
|
||||||
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: cannot find attribute `derive_Clone` in this scope
|
error: cannot find attribute `derive_Clone` in this scope
|
||||||
--> $DIR/issue-32655.rs:15:7
|
--> $DIR/issue-32655.rs:15:7
|
||||||
|
|
|
|
||||||
LL | #[derive_Clone]
|
LL | #[derive_Clone]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `derive_const`
|
||||||
|
|
|
||||||
|
::: $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | pub macro derive_const($item:item) {
|
||||||
|
| ---------------------- similarly named attribute macro `derive_const` defined here
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,7 @@ error[E0428]: the name `A` is defined multiple times
|
||||||
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:13
|
--> $DIR/issue-69396-const-no-type-in-macro.rs:4:13
|
||||||
|
|
|
|
||||||
LL | const A = "A".$fn();
|
LL | const A = "A".$fn();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^ `A` redefined here
|
||||||
| |
|
|
||||||
| `A` redefined here
|
|
||||||
| previous definition of the value `A` here
|
|
||||||
...
|
...
|
||||||
LL | / suite! {
|
LL | / suite! {
|
||||||
LL | | len;
|
LL | | len;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
//~^ NOTE required by a bound in this
|
|
||||||
let whatever: [u32; 10] = (0..10).collect();
|
let whatever: [u32; 10] = (0..10).collect();
|
||||||
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
|
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
|
||||||
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
|
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
|
||||||
--> $DIR/collect-into-array.rs:3:31
|
--> $DIR/collect-into-array.rs:2:31
|
||||||
|
|
|
|
||||||
LL | let whatever: [u32; 10] = (0..10).collect();
|
LL | let whatever: [u32; 10] = (0..10).collect();
|
||||||
| ^^^^^^^ ------- required by a bound introduced by this call
|
| ^^^^^^^ ------- required by a bound introduced by this call
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
fn process_slice(data: &[i32]) {
|
fn process_slice(data: &[i32]) {
|
||||||
//~^ NOTE required by a bound in this
|
|
||||||
//~| NOTE required by a bound in this
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/collect-into-slice.rs:8:9
|
--> $DIR/collect-into-slice.rs:6:9
|
||||||
|
|
|
|
||||||
LL | let some_generated_vec = (0..10).collect();
|
LL | let some_generated_vec = (0..10).collect();
|
||||||
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -9,7 +9,7 @@ LL | let some_generated_vec = (0..10).collect();
|
||||||
= help: unsized locals are gated as an unstable feature
|
= help: unsized locals are gated as an unstable feature
|
||||||
|
|
||||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||||
--> $DIR/collect-into-slice.rs:8:38
|
--> $DIR/collect-into-slice.rs:6:38
|
||||||
|
|
|
|
||||||
LL | let some_generated_vec = (0..10).collect();
|
LL | let some_generated_vec = (0..10).collect();
|
||||||
| ^^^^^^^ doesn't have a size known at compile-time
|
| ^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
@ -22,7 +22,7 @@ LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
||||||
| ^ required by this bound in `collect`
|
| ^ required by this bound in `collect`
|
||||||
|
|
||||||
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
|
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
|
||||||
--> $DIR/collect-into-slice.rs:8:30
|
--> $DIR/collect-into-slice.rs:6:30
|
||||||
|
|
|
|
||||||
LL | let some_generated_vec = (0..10).collect();
|
LL | let some_generated_vec = (0..10).collect();
|
||||||
| ^^^^^^^ ------- required by a bound introduced by this call
|
| ^^^^^^^ ------- required by a bound introduced by this call
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#[derive_const(Default)] //~ ERROR use of unstable library feature
|
||||||
|
pub struct S;
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0658]: use of unstable library feature 'derive_const'
|
||||||
|
--> $DIR/derive-const-gate.rs:1:3
|
||||||
|
|
|
||||||
|
LL | #[derive_const(Default)]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(derive_const)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(derive_const)]
|
||||||
|
|
||||||
|
pub struct A;
|
||||||
|
|
||||||
|
impl Default for A {
|
||||||
|
fn default() -> A { A }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_const(Default)]
|
||||||
|
pub struct S(A);
|
||||||
|
//~^ cannot call non-const fn
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,14 @@
|
||||||
|
error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions
|
||||||
|
--> $DIR/derive-const-non-const-type.rs:10:14
|
||||||
|
|
|
||||||
|
LL | #[derive_const(Default)]
|
||||||
|
| ------- in this derive macro expansion
|
||||||
|
LL | pub struct S(A);
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0015`.
|
|
@ -0,0 +1,19 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)]
|
||||||
|
|
||||||
|
pub struct A;
|
||||||
|
|
||||||
|
impl const Default for A {
|
||||||
|
fn default() -> A { A }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const PartialEq for A {
|
||||||
|
fn eq(&self, _: &A) -> bool { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_const(Default, PartialEq)]
|
||||||
|
pub struct S((), A);
|
||||||
|
|
||||||
|
const _: () = assert!(S((), A) == S::default());
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9286a1beba5b28b115bad67de2ae91fb1c61eb0b
|
Subproject commit a3dfea71ca0c888a88111086898aa833c291d497
|
|
@ -573,6 +573,7 @@ fallback = [
|
||||||
"/src/llvm-project" = ["@cuviper"]
|
"/src/llvm-project" = ["@cuviper"]
|
||||||
"/src/rustdoc-json-types" = ["rustdoc"]
|
"/src/rustdoc-json-types" = ["rustdoc"]
|
||||||
"/src/stage0.json" = ["bootstrap"]
|
"/src/stage0.json" = ["bootstrap"]
|
||||||
|
"/src/test/ui" = ["compiler"]
|
||||||
"/src/tools/cargo" = ["@ehuss", "@joshtriplett"]
|
"/src/tools/cargo" = ["@ehuss", "@joshtriplett"]
|
||||||
"/src/tools/compiletest" = ["bootstrap"]
|
"/src/tools/compiletest" = ["bootstrap"]
|
||||||
"/src/tools/linkchecker" = ["@ehuss"]
|
"/src/tools/linkchecker" = ["@ehuss"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue