diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 04753926c3e2a..a3decff3ae7e1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -541,7 +541,7 @@ impl<'a> TraitDef<'a> { self.generics.to_generics(cx, self.span, type_ident, generics); // Create the generic parameters - params.extend(generics.params.iter().map(|param| match param.kind { + params.extend(generics.params.iter().map(|param| match ¶m.kind { GenericParamKind::Lifetime { .. } => param.clone(), GenericParamKind::Type { .. } => { // I don't think this can be moved out of the loop, since @@ -561,7 +561,18 @@ impl<'a> TraitDef<'a> { cx.typaram(self.span, param.ident, vec![], bounds, None) } - GenericParamKind::Const { .. } => param.clone(), + GenericParamKind::Const { ty, kw_span, .. } => { + let const_nodefault_kind = GenericParamKind::Const { + ty: ty.clone(), + kw_span: kw_span.clone(), + + // We can't have default values inside impl block + default: None, + }; + let mut param_clone = param.clone(); + param_clone.kind = const_nodefault_kind; + param_clone + } })); // and similarly for where clauses diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 327beca218e1d..87e28f7fcc592 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -758,17 +758,14 @@ impl<'a> Resolver<'a> { { let mut candidates = Vec::new(); let mut seen_modules = FxHashSet::default(); - let not_local_module = crate_name.name != kw::Crate; - let mut worklist = - vec![(start_module, Vec::::new(), true, not_local_module)]; + let mut worklist = vec![(start_module, Vec::::new(), true)]; let mut worklist_via_import = vec![]; - while let Some((in_module, path_segments, accessible, in_module_is_extern)) = - match worklist.pop() { - None => worklist_via_import.pop(), - Some(x) => Some(x), - } - { + while let Some((in_module, path_segments, accessible)) = match worklist.pop() { + None => worklist_via_import.pop(), + Some(x) => Some(x), + } { + let in_module_is_extern = !in_module.def_id().unwrap().is_local(); // We have to visit module children in deterministic order to avoid // instabilities in reported imports (#43552). in_module.for_each_child(self, |this, ident, ns, name_binding| { @@ -850,11 +847,10 @@ impl<'a> Resolver<'a> { name_binding.is_extern_crate() && lookup_ident.span.rust_2018(); if !is_extern_crate_that_also_appears_in_prelude { - let is_extern = in_module_is_extern || name_binding.is_extern_crate(); // add the module to the lookup if seen_modules.insert(module.def_id().unwrap()) { if via_import { &mut worklist_via_import } else { &mut worklist } - .push((module, path_segments, child_accessible, is_extern)); + .push((module, path_segments, child_accessible)); } } } diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 37538267b866a..fd7c50e978800 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1492,28 +1492,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) { self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output); } - - if let Some(sp) = fcx.ret_coercion_span.get() { - // If the closure has an explicit return type annotation, - // then a type error may occur at the first return expression we - // see in the closure (if it conflicts with the declared - // return type). Skip adding a note in this case, since it - // would be incorrect. - if !err.span.primary_spans().iter().any(|&span| span == sp) { - let hir = fcx.tcx.hir(); - let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id)); - if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) { - err.span_note( - sp, - &format!( - "return type inferred to be `{}` here", - fcx.resolve_vars_if_possible(expected) - ), - ); - } - } - } - err } diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index d879b6e97dcfb..e5fcdcfa74315 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -37,6 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.suggest_missing_parentheses(err, expr); self.note_need_for_fn_pointer(err, expected, expr_ty); self.note_internal_mutation_in_method(err, expr, expected, expr_ty); + self.report_closure_infered_return_type(err, expected) } // Requires that the two types unify, and prints an error message if @@ -1061,4 +1062,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => false, } } + + // Report the type inferred by the return statement. + fn report_closure_infered_return_type( + &self, + err: &mut DiagnosticBuilder<'_>, + expected: Ty<'tcx>, + ) { + if let Some(sp) = self.ret_coercion_span.get() { + // If the closure has an explicit return type annotation, + // then a type error may occur at the first return expression we + // see in the closure (if it conflicts with the declared + // return type). Skip adding a note in this case, since it + // would be incorrect. + if !err.span.primary_spans().iter().any(|&span| span == sp) { + let hir = self.tcx.hir(); + let body_owner = hir.body_owned_by(hir.enclosing_body_owner(self.body_id)); + if self.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) { + err.span_note( + sp, + &format!( + "return type inferred to be `{}` here", + self.resolve_vars_if_possible(expected) + ), + ); + } + } + } + } } diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index da2415e361077..9b629e19be53d 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -334,6 +334,8 @@ impl Ipv4Addr { /// An IPv4 address representing an unspecified address: 0.0.0.0 /// + /// This corresponds to the constant `INADDR_ANY` in other languages. + /// /// # Examples /// /// ``` @@ -342,6 +344,7 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::UNSPECIFIED; /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); /// ``` + #[doc(alias = "INADDR_ANY")] #[stable(feature = "ip_constructors", since = "1.30.0")] pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0); diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 1e79bd0912884..c2a971d637513 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -401,7 +401,7 @@ crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Ty return Generic(kw::SelfUpper); } Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => { - return Generic(Symbol::intern(&format!("{:#}", path.print(&cx.cache, cx.tcx)))); + return Generic(Symbol::intern(&path.whole_name())); } Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true, _ => false, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a004ee5054ed6..4a091ee911425 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -453,48 +453,6 @@ impl clean::GenericArgs { } } -impl clean::PathSegment { - crate fn print<'a, 'tcx: 'a>( - &'a self, - cache: &'a Cache, - tcx: TyCtxt<'tcx>, - ) -> impl fmt::Display + 'a + Captures<'tcx> { - display_fn(move |f| { - if f.alternate() { - write!(f, "{}{:#}", self.name, self.args.print(cache, tcx)) - } else { - write!(f, "{}{}", self.name, self.args.print(cache, tcx)) - } - }) - } -} - -impl clean::Path { - crate fn print<'a, 'tcx: 'a>( - &'a self, - cache: &'a Cache, - tcx: TyCtxt<'tcx>, - ) -> impl fmt::Display + 'a + Captures<'tcx> { - display_fn(move |f| { - if self.global { - f.write_str("::")? - } - - for (i, seg) in self.segments.iter().enumerate() { - if i > 0 { - f.write_str("::")? - } - if f.alternate() { - write!(f, "{:#}", seg.print(cache, tcx))?; - } else { - write!(f, "{}", seg.print(cache, tcx))?; - } - } - Ok(()) - }) - } -} - crate fn href(did: DefId, cache: &Cache) -> Option<(String, ItemType, Vec)> { if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private { return None; diff --git a/src/test/ui/closures/issue-84128.rs b/src/test/ui/closures/issue-84128.rs new file mode 100644 index 0000000000000..f81d7cfaa654b --- /dev/null +++ b/src/test/ui/closures/issue-84128.rs @@ -0,0 +1,16 @@ +// test for issue 84128 +// missing suggestion for similar ADT type with diffetent generic paramenter +// on closure ReturnNoExpression + +struct Foo(T); + +fn main() { + || { + if false { + return Foo(0); + } + + Foo(()) + //~^ ERROR mismatched types [E0308] + }; +} diff --git a/src/test/ui/closures/issue-84128.stderr b/src/test/ui/closures/issue-84128.stderr new file mode 100644 index 0000000000000..70d9273ddf7ce --- /dev/null +++ b/src/test/ui/closures/issue-84128.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-84128.rs:13:13 + | +LL | Foo(()) + | ^^ expected integer, found `()` + | +note: return type inferred to be `{integer}` here + --> $DIR/issue-84128.rs:10:20 + | +LL | return Foo(0); + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/derives/derive-macro-const-default.rs b/src/test/ui/derives/derive-macro-const-default.rs new file mode 100644 index 0000000000000..a844f2d20237b --- /dev/null +++ b/src/test/ui/derives/derive-macro-const-default.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(incomplete_features)] +#![feature(const_generics_defaults)] + +#[derive(Clone, PartialEq, Debug)] +struct Example([T; N]); + +fn main() { + let a = Example([(); 16]); + let b = a.clone(); + if a != b { + let _c = format!("{:?}", a); + } +} diff --git a/src/test/ui/resolve/auxiliary/issue-80079.rs b/src/test/ui/resolve/auxiliary/issue-80079.rs new file mode 100644 index 0000000000000..190ca75aba86a --- /dev/null +++ b/src/test/ui/resolve/auxiliary/issue-80079.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] + +pub mod public { + use private_import; + + // should not be suggested since it is private + struct Foo; + + mod private_module { + // should not be suggested since it is private + pub struct Foo; + } +} + +mod private_import { + // should not be suggested since it is private + pub struct Foo; +} diff --git a/src/test/ui/resolve/issue-80079.rs b/src/test/ui/resolve/issue-80079.rs new file mode 100644 index 0000000000000..4795ed062c8f6 --- /dev/null +++ b/src/test/ui/resolve/issue-80079.rs @@ -0,0 +1,12 @@ +// aux-build:issue-80079.rs + +// using a module from another crate should not cause errors to suggest private +// items in that module + +extern crate issue_80079; + +use issue_80079::public; + +fn main() { + let _ = Foo; //~ ERROR cannot find value `Foo` in this scope +} diff --git a/src/test/ui/resolve/issue-80079.stderr b/src/test/ui/resolve/issue-80079.stderr new file mode 100644 index 0000000000000..93e8c0341a13a --- /dev/null +++ b/src/test/ui/resolve/issue-80079.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `Foo` in this scope + --> $DIR/issue-80079.rs:11:13 + | +LL | let _ = Foo; + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 363105a9f09c0..f31a24738df6c 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -136,9 +136,7 @@ impl EarlyProps { props.aux_crate.push(ac); } - if let Some(r) = config.parse_revisions(ln) { - props.revisions.extend(r); - } + config.parse_and_update_revisions(ln, &mut props.revisions); props.should_fail = props.should_fail || config.parse_name_directive(ln, "should-fail"); }); @@ -432,9 +430,7 @@ impl TestProps { self.compile_flags.push(format!("--edition={}", edition)); } - if let Some(r) = config.parse_revisions(ln) { - self.revisions.extend(r); - } + config.parse_and_update_revisions(ln, &mut self.revisions); if self.run_flags.is_none() { self.run_flags = config.parse_run_flags(ln); @@ -723,9 +719,16 @@ impl Config { self.parse_name_value_directive(line, "compile-flags") } - fn parse_revisions(&self, line: &str) -> Option> { - self.parse_name_value_directive(line, "revisions") - .map(|r| r.split_whitespace().map(|t| t.to_string()).collect()) + fn parse_and_update_revisions(&self, line: &str, existing: &mut Vec) { + if let Some(raw) = self.parse_name_value_directive(line, "revisions") { + let mut duplicates: HashSet<_> = existing.iter().cloned().collect(); + for revision in raw.split_whitespace().map(|r| r.to_string()) { + if !duplicates.insert(revision.clone()) { + panic!("Duplicate revision: `{}` in line `{}`", revision, raw); + } + existing.push(revision); + } + } } fn parse_run_flags(&self, line: &str) -> Option { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index c41b43cdd0b53..ca7458d255c3c 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -248,3 +248,10 @@ fn test_extract_version_range() { assert_eq!(extract_version_range(" - 4.5.6", extract_llvm_version), None); assert_eq!(extract_version_range("0 -", extract_llvm_version), None); } + +#[test] +#[should_panic(expected = "Duplicate revision: `rpass1` in line ` rpass1 rpass1`")] +fn test_duplicate_revisions() { + let config = config(); + parse_rs(&config, "// revisions: rpass1 rpass1"); +}