jiebi/CodeConvo huggingface dataset:
Change:
On mobile using both firefox and Brave. !
This is presumably a rustdoc issue, unless our css somehow affects it, but I doubt it.
Taking a look.

Discussion:
pixels to avoid overflowing the topbar when the user sets a bigger font size. */ font-size: 24px; <del> } .mobile-topbar h2 a { display: block; text-overflow: ellipsis; overflow: hidden; </del> white-space: nowrap; <ins> text-overflow: ellipsis; </ins> } .mobile-topbar .logo-container > img {

const mobileTitle = document.createElement("h2"); mobileTitle.className = "location"; if (hasClass(document.querySelector(".rustdoc"), "crate")) { <del> mobileTitle.innerText = `Crate ${window.currentCrate}`; </del> <ins> mobileTitle.innerHTML = `Crate <a href="#">${window.currentCrate}</a>`; </ins> } else if (locationTitle) { mobileTitle.innerHTML = locationTitle.innerHTML; }

<ins> // Checks that if the crate name is too long on mobile, it will not grow and overflow its parent // (thanks to text overflow ellipsis). go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // First we change the title to make it big. set-window-size: (350, 800) // We ensure that the "format" of the title is the same as the one we'll use. assert-text: (".mobile-topbar .location a", "test_docs") // We store the height we know is correct. store-property: (".mobile-topbar .location", {"offsetHeight": height}) // We change the crate name to something longer. set-text: (".mobile-topbar .location a", "cargo_packager_resource_resolver") // And we check that the size remained the same. assert-property: (".mobile-topbar .location", {"offsetHeight": |height|}) // Now we check if it works for the non-crate pages as well. go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // We store the height we know is correct. store-property: (".mobile-topbar .location", {"offsetHeight": height}) set-text: (".mobile-topbar .location a", "Something_incredibly_long_because") // And we check that the size remained the same. assert-property: (".mobile-topbar .location", {"offsetHeight": |height|}) </ins>

set-window-size: (600, 600) go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" // It shouldn't have an overflow in the topbar either. <del> store-property: (".mobile-topbar h2", {"scrollWidth": scrollWidth}) assert-property: (".mobile-topbar h2", {"clientWidth": |scrollWidth|}) </del> <ins> store-property: (".mobile-topbar", {"scrollWidth": scrollWidth}) assert-property: (".mobile-topbar", {"clientWidth": |scrollWidth|}) </ins> assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"}) // Check wrapping for top main-heading h1 and out-of-band.
Change:
Code 2 Few ICEs with new intrinsic <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <details<summary<strongBacktrace 1</strong</summary<p</p</details<details<summary<strongBacktrace 2</strong</summary<p</p, so cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
like the intrinsic wasn't to the list at 2 Appears to be the same crash, just panicking at different points. label +F-core_intrinsics -needs-triage
claim
Would that check if the pointer address is constant or the referenced value is constant? I think for , one would expect the reference to be coerced to a . I don't know what to do for slices though.
I think checks for whether or not the the pointer address is statically known. I don't think mutable variables in function bodies can be statically known and references to globals are guaranteed to fold to false. That covers all the cases I thought about but I'm fairly confident I missed something.
They can be. It is usually the result of inlineing. Detecting that is kind of the point of the intrinsic.

Discussion:
ifn!("llvm.is.constant.isize", fn(t_isize) -> i1); ifn!("llvm.is.constant.f32", fn(t_f32) -> i1); ifn!("llvm.is.constant.f64", fn(t_f64) -> i1); <ins> ifn!("llvm.is.constant.ptr", fn(ptr) -> i1); </ins> ifn!("llvm.expect.i1", fn(i1, i1) -> i1); ifn!("llvm.eh.typeid.for", fn(ptr) -> t_i32);

sym::likely => { self.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(true)]) } <del> sym::is_val_statically_known => self.call_intrinsic( &format!("llvm.is.constant.{:?}", args[0].layout.immediate_llvm_type(self.cx)), &[args[0].immediate()], ), </del> <ins> sym::is_val_statically_known => { let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx); match self.type_kind(intrinsic_type) { TypeKind::Pointer | TypeKind::Integer | TypeKind::Float | TypeKind::Double => { self.call_intrinsic( &format!("llvm.is.constant.{:?}", intrinsic_type), &[args[0].immediate()], ) } _ => self.const_bool(false), } } </ins> sym::unlikely => self .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]), kw::Try => {

// CHECK: ret i32 2 _bool(b) } <ins> #[inline] pub fn _iref(a: &u8) -> i32 { if unsafe { is_val_statically_known(a) } { 5 } else { 4 } } // CHECK-LABEL: @_iref_borrow( #[no_mangle] pub fn _iref_borrow() -> i32 { // CHECK: ret i32 4 _iref(&0) } // CHECK-LABEL: @_iref_arg( #[no_mangle] pub fn _iref_arg(a: &u8) -> i32 { // CHECK: ret i32 4 _iref(a) } #[inline] pub fn _slice_ref(a: &[u8]) -> i32 { if unsafe { is_val_statically_known(a) } { 7 } else { 6 } } // CHECK-LABEL: @_slice_ref_borrow( #[no_mangle] pub fn _slice_ref_borrow() -> i32 { // CHECK: ret i32 6 _slice_ref(&[0;3]) } // CHECK-LABEL: @_slice_ref_arg( #[no_mangle] pub fn _slice_ref_arg(a: &[u8]) -> i32 { // CHECK: ret i32 6 _slice_ref(a) } </ins>
Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: ! Instead, this happened: ! This is issue from First screenshot is of and second is of
Probably , it shouldn't have affected glob re-exports but maybe did (cc
Taking a look.
Same issue with a simple reexport:
That's what was meant to do, it wasn't meant to affect globs though.
I think there is another issue with how it's handled because nothing is listed on the item itself too: !
Ok so it's the expected output for a non-glob reexport. I wrote the fix for glob reexports, just need to add tests.
Latest nightly fixed the issue for but it didn't fix the issue for . In latest nightly below example doesn't work its last working version was also .
Noted. Sending a fix for it as well. :)
Fixed in

Discussion:
) } <ins> fn is_glob_import(tcx: TyCtxt<'_>, import_id: LocalDefId) -> bool { if let Some(node) = tcx.opt_hir_node_by_def_id(import_id) && let hir::Node::Item(item) = node && let hir::ItemKind::Use(_, use_kind) = item.kind { use_kind == hir::UseKind::Glob } else { false } } </ins> fn generate_item_with_correct_attrs( cx: &mut DocContext<'_>, kind: ItemKind,

) -> Item { let target_attrs = inline::load_attrs(cx, def_id); let attrs = if let Some(import_id) = import_id { <ins> // glob reexports are treated the same as `#[doc(inline)]` items. // // For glob re-exports the item may or may not exist to be re-exported (potentially the cfgs // on the path up until the glob can be removed, and only cfgs on the globbed item itself // matter), for non-inlined re-exports see #85043. </ins> let is_inline = inline::load_attrs(cx, import_id.to_def_id()) .lists(sym::doc) .get_word_attr(sym::inline) <del> .is_some(); </del> <ins> .is_some() || (is_glob_import(cx.tcx, import_id) && (cx.render_options.document_hidden || !cx.tcx.is_doc_hidden(def_id))); </ins> let mut attrs = get_all_import_attributes(cx, import_id, def_id, is_inline); add_without_unwanted_attributes(&mut attrs, target_attrs, is_inline, None); attrs

<ins> // This test ensures that non-glob reexports don't get their attributes merge with // the reexported item whereas glob reexports do. // Regression test for <https://github.com/rust-lang/rust/issues/120487>. #![crate_name = "foo"] #![feature(doc_cfg)] // @has 'foo/index.html' // There are two items. // @count - '//*[@class="item-table"]//div[@class="item-name"]' 2 // Only one of them should have an attribute. // @count - '//*[@class="item-table"]//div[@class="item-name"]/*[@class="stab portability"]' 1 mod a { #[doc(cfg(not(feature = "a")))] #[cfg(not(feature = "a"))] pub struct Test1; } mod b { #[doc(cfg(not(feature = "a")))] #[cfg(not(feature = "a"))] pub struct Test2; } // @has 'foo/struct.Test1.html' // @count - '//*[@id="main-content"]/*[@class="item-info"]' 1 // @has - '//*[@id="main-content"]/*[@class="item-info"]' 'Available on non-crate feature a only.' pub use a::*; // @has 'foo/struct.Test2.html' // @count - '//*[@id="main-content"]/*[@class="item-info"]' 0 pub use b::Test2; </ins>
Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: (source: from the Community Discord server) I expected to see this happen: panic, out of bounds read Instead, this happened: In debug: SEGMENTATION VIOLATION In release: Heap buffer overflow In miri: Undefined Behavior: out-of-bounds pointer use: alloc893 has size 8192, so pointer to bytes starting at offset 0 is out-of-bounds Stable (1.75.0) and Nightly (1.77.0-nightly 2024-02-01 ) have the issue. uses to read from the er, using the 's len as the filled value. The function calls with the dodgy read amount. uses the value as the upper bound of the read buffer. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
It's unclear whether should be fixed to check that is in bounds should be fixed to check that the () is in bounds Reading the current safety comments, it appears that is in the wrong: this is violated as only 8192 bytes are intiialised. I would personally suggest that be updated to add a bounds check.
claim

Discussion:
F: FnOnce(&mut [u8]) -> Result<usize>, { let n = read(cursor.ensure_init().init_mut())?; <ins> assert!( n <= cursor.capacity(), "read should not return more bytes than there is capacity for in the read buffer" ); </ins> unsafe { <del> // SAFETY: we initialised using `ensure_init` so there is no uninit data to advance to. </del> <ins> // SAFETY: we initialised using `ensure_init` so there is no uninit data to advance to // and we have checked that the read amount is not over capacity (see #120603) </ins> cursor.advance(n); } Ok(())

use super::{repeat, BorrowedBuf, Cursor, SeekFrom}; use crate::cmp::{self, min}; <del> use crate::io::{self, IoSlice, IoSliceMut}; </del> <ins> use crate::io::{self, IoSlice, IoSliceMut, DEFAULT_BUF_SIZE}; </ins> use crate::io::{BufRead, BufReader, Read, Seek, Write}; use crate::mem::MaybeUninit; use crate::ops::Deref;

[255; 128].take(64).read_buf(buf.unfilled()).unwrap(); }); } <ins> // Issue #120603 #[test] #[should_panic = "read should not return more bytes than there is capacity for in the read buffer"] fn read_buf_broken_read() { struct MalformedRead; impl Read for MalformedRead { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { // broken length calculation Ok(buf.len() + 1) } } let _ = BufReader::new(MalformedRead).fill_buf(); } #[test] fn read_buf_full_read() { struct FullRead; impl Read for FullRead { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { Ok(buf.len()) } } assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE); } </ins>
Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: Note that is not marked as internal I expected to see this happen: code compiles Instead, this happened: ` Maybe the lint should ignore code from expansions? <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --:
On , the expansion of with contains a call to : is tagged with , but not .

Discussion:
/// Builds the whole `assert!` expression. For example, `let elem = 1; assert!(elem == 1);` expands to: /// /// ```rust <del> /// #![feature(generic_assert_internals)] </del> /// let elem = 1; /// { ///   #[allow(unused_imports)]

#[rustc_builtin_macro] #[macro_export] #[rustc_diagnostic_item = "assert_macro"] <del> #[allow_internal_unstable(panic_internals, edition_panic, generic_assert_internals)] </del> <ins> #[allow_internal_unstable( core_intrinsics, panic_internals, edition_panic, generic_assert_internals )] </ins> macro_rules! assert { ($cond:expr $(,)?) => {{ /* compiler built-in */ }}; ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
Change:
Right: Wrong: The first argument to is partially moved. GVN causes the second argument to use the partially moved value:
I can't provoke the miscompilation on beta using this example (just had to replace with to make it build), so I don't think there's any need to rush to fix this. (Some part of GVN is used in the beta that's about to become stable, but it looks like it doesn't have this bug in it)
Cc
WG-prioritization assigning priority (). label -I-prioritize +P-medium

Discussion:
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) { if let Operand::Move(place) = *operand <del> && let Some(local) = place.as_local() && self.reused_locals.contains(local) </del> <ins> && !place.is_indirect_first_projection() && self.reused_locals.contains(place.local) </ins> { *operand = Operand::Copy(place); }

<ins> - // MIR for `fn0` before GVN + // MIR for `fn0` after GVN fn fn0() -> () { let mut _0: (); let mut _1: usize; let mut _2: [u128; 6]; let mut _3: ([u128; 6],); let mut _4: ([u128; 6],); let mut _5: (); bb0: { _1 = const 1_usize; _2 = [const 42_u128; 6]; -         _2[_1] = const 1_u128; +         _2[1 of 2] = const 1_u128; _3 = (_2,); _4 = _3; -         _5 = fn1(move (_3.0: [u128; 6]), _4) -> [return: bb1, unwind unreachable]; +         _5 = fn1((_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable]; } bb1: { return; } } </ins>

<ins> // unit-test: GVN #![feature(custom_mir, core_intrinsics)] extern crate core; use core::intrinsics::mir::*; #[custom_mir(dialect = "runtime", phase = "initial")] fn fn0() { // CHECK-LABEL: fn fn0( mir! { let a: usize; let b: [u128; 6]; let c: ([u128; 6],); let d: ([u128; 6],); let x: (); { // CHECK: bb0: { // CHECK-NEXT: _1 = const 1_usize; // CHECK-NEXT: _2 = [const 42_u128; 6]; // CHECK-NEXT: _2[1 of 2] = const 1_u128; // CHECK-NEXT: _3 = (_2,); // CHECK-NEXT: _4 = _3; // CHECK-NEXT: _5 = fn1((_3.0: [u128; 6]), _3) a = 1_usize; b = [42; 6]; b[a] = 1; c = (b,); d = c; Call(x = fn1(Move(c.0), d), ReturnTo(bb1), UnwindUnreachable()) } bb1 = { Return() } } } #[inline(never)] fn fn1(a: [u128; 6], mut b: ([u128; 6],)) { b.0 = [0; 6]; } fn main() { fn0(); } // EMIT_MIR gvn_copy_moves.fn0.GVN.diff </ins>

_5 = ((_2 as Break).0: std::result::Result<std::convert::Infallible, i32>); StorageLive(_6); _6 = _5; <del> _12 = move ((_5 as Err).0: i32); </del> <ins> _12 = ((_5 as Err).0: i32); </ins> _0 = Result::<i32, i32>::Err(_12); StorageDead(_6); StorageDead(_2);

} bb4: { <del> _10 = move ((_1 as Err).0: i32); </del> <ins> _10 = ((_1 as Err).0: i32); </ins> StorageLive(_11); _11 = Result::<Infallible, i32>::Err(_10); _2 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _11);

} bb5: { <del> _9 = move ((_1 as Ok).0: i32); </del> <ins> _9 = ((_1 as Ok).0: i32); </ins> _2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(_9); goto -> bb3; }
Change:
<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --While I was trying to add lifetimes for picoserve's I got into ICE (1.) had a dep of picoserve as 2. That code isn't finished and should not compile yet <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: has ice files
rustc 1.75.0 ( 2023-12-21) binary: rustc commit-hash: commit-date: 2023-12-21 host: x86_64-unknown-linux-gnu release: 1.75.0 LLVM version: 17.0.6 Here ICE is also present
Backtrace from one of the linked files pasted below for the sake of searchability and preservation: <details<summaryBacktrace</summary</details

Discussion:
let (suitable_region_binding_scope, bound_region) = loop { let def_id = match region.kind() { ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?, <del> ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(), </del> <ins> ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?, </ins> _ => return None, // not a free region }; let scope = self.local_parent(def_id);

<ins> // edition:2021 #[allow(async_fn_in_trait)] pub trait BleRadio<'a> { async fn transmit(&mut self); } </ins>

<ins> // aux-build:bad-region.rs // edition:2021 #![allow(async_fn_in_trait)] extern crate bad_region as jewel; use jewel::BleRadio; pub struct Radio {} impl BleRadio for Radio { //~^ ERROR implicit elided lifetime not allowed here async fn transmit(&mut self) {} } fn main() {} </ins>

<ins> error[E0726]: implicit elided lifetime not allowed here --> $DIR/bad-region.rs:12:6 | LL | impl BleRadio for Radio { |      ^^^^^^^^ expected lifetime parameter | help: indicate the anonymous lifetime | LL | impl BleRadio<'_> for Radio { |              ++++ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0726`. </ins>
Change:
I was developing one trait in one crate, changing it to use a lifetime, and forgot to add it to the other crate's implementation. The compiler shows de correct error message but breaks. If I fix the code, adding the lifetime to the trait, de compiler works. If it is in the same crate also works. : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Same backtrace as .
Thanks for the minimized test! I'll fix this tomorrow.

Discussion:
let (suitable_region_binding_scope, bound_region) = loop { let def_id = match region.kind() { ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?, <del> ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(), </del> <ins> ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?, </ins> _ => return None, // not a free region }; let scope = self.local_parent(def_id);

<ins> // edition:2021 #[allow(async_fn_in_trait)] pub trait BleRadio<'a> { async fn transmit(&mut self); } </ins>

<ins> // aux-build:bad-region.rs // edition:2021 #![allow(async_fn_in_trait)] extern crate bad_region as jewel; use jewel::BleRadio; pub struct Radio {} impl BleRadio for Radio { //~^ ERROR implicit elided lifetime not allowed here async fn transmit(&mut self) {} } fn main() {} </ins>

<ins> error[E0726]: implicit elided lifetime not allowed here --> $DIR/bad-region.rs:12:6 | LL | impl BleRadio for Radio { |      ^^^^^^^^ expected lifetime parameter | help: indicate the anonymous lifetime | LL | impl BleRadio<'_> for Radio { |              ++++ error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0726`. </ins>
Change:
Per we should have the docs licensed correctly. Nominating.
I can have a look at this.

Discussion:
/nd/ /llvm/ version.md <del> *.tex </del> keywords.md x86_64-apple-darwin/ x86_64-unknown-linux-gnu/

BASE_DOC_OPTS := --standalone --toc --number-sections HTML_OPTS = $(BASE_DOC_OPTS) --to=html5 --section-divs --css=rust.css  <del> --include-before-body=doc/version_info.html --include-in-header=doc/favicon.inc TEX_OPTS = $(BASE_DOC_OPTS) --include-before-body=doc/version.md --to=latex </del> <ins> --include-before-body=doc/version_info.html  --include-in-header=doc/favicon.inc --include-after-body=doc/footer.inc TEX_OPTS = $(BASE_DOC_OPTS) --include-before-body=doc/version.md  --from=markdown --include-before-body=doc/footer.tex --to=latex </ins> EPUB_OPTS = $(BASE_DOC_OPTS) --to=epub D := $(S)src/doc

@$(call E, cp: $@) $(Q)cp -a $< $@ 2> /dev/null <ins> HTML_DEPS += doc/favicon.inc doc/favicon.inc: $(D)/favicon.inc | doc/ @$(call E, cp: $@) $(Q)cp -a $< $@ 2> /dev/null </ins> doc/full-toc.inc: $(D)/full-toc.inc | doc/ @$(call E, cp: $@) $(Q)cp -a $< $@ 2> /dev/null <del> HTML_DEPS += doc/favicon.inc doc/favicon.inc: $(D)/favicon.inc | doc/ </del> <ins> HTML_DEPS += doc/footer.inc doc/footer.inc: $(D)/footer.inc | doc/ @$(call E, cp: $@) $(Q)cp -a $< $@ 2> /dev/null doc/footer.tex: $(D)/footer.tex | doc/ </ins> @$(call E, cp: $@) $(Q)cp -a $< $@ 2> /dev/null

$(CFG_PANDOC) $(HTML_OPTS) --include-in-header=doc/full-toc.inc --output=$@ DOCS += doc/rust.tex <del> doc/rust.tex: $(D)/rust.md doc/version.md | doc/ </del> <ins> doc/rust.tex: $(D)/rust.md doc/footer.tex doc/version.md | doc/ </ins> @$(call E, pandoc: $@) $(Q)$(CFG_NODE) $(D)/prep.js $< |  $(CFG_PANDOC) $(TEX_OPTS) --output=$@

$(CFG_PANDOC) $(HTML_OPTS) --output=$@ DOCS += doc/tutorial.tex <del> doc/tutorial.tex: $(D)/tutorial.md doc/version.md </del> <ins> doc/tutorial.tex: $(D)/tutorial.md doc/footer.tex doc/version.md </ins> @$(call E, pandoc: $@) $(Q)$(CFG_NODE) $(D)/prep.js $< |  $(CFG_PANDOC) $(TEX_OPTS) --output=$@

<ins> <footer><p> Copyright &copy; 2011-2014 The Rust Project Developers. Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> or the <a href="http://opensource.org/licenses/MIT">MIT license</a>, at your option. </p><p> This file may not be copied, modified, or distributed except according to those terms. </p></footer> </ins>

<ins> Copyright © 2011-2014 The Rust Project Developers. Licensed under the href{http://www.apache.org/licenses/LICENSE-2.0}{Apache License, Version 2.0} or the href{http://opensource.org/licenses/MIT}{MIT license}, at your option. This file may not be copied, modified, or distributed except according to those terms. </ins>

body { margin: 0 auto; padding: 0 15px; <del> margin-bottom: 4em; </del> font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; color: #333;

margin: 0 0 10px; } <ins> footer { border-top: 1px solid #ddd; font-size: 12px; font-style: italic; padding-top: 4px; margin-top: 4em; margin-bottom: 1em; } </ins> /* Links layout ========================================================================== */ a {